-
Notifications
You must be signed in to change notification settings - Fork 46
Separate send xts and send blocks #487
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| fn create_extrinsics<PB>( | ||
| fn create_extrinsics<PB, Signer>( | ||
| genesis_hash: HashFor<PB>, | ||
| signer: Signer, | ||
| calls: Vec<OpaqueCall>, | ||
| nonce: &mut u32, | ||
| ) -> Result<Vec<OpaqueExtrinsic>> | ||
| mut nonce: u32, | ||
| ) -> Result<(Vec<OpaqueExtrinsic>, u32)> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Take the signer as parameter (rather than having the Ed25519Seal::unseal()?; side-effect in the function) and the nonce is now an input parameter and returned in the result.
| .unzip(); | ||
|
|
||
| prepare_and_send_xts_and_block::<_, SB, _, _>( | ||
| ocall_api.send_sidechain_blocks(blocks)?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sending the sidechain blocks is now done by just calling the corresponding method on ocall_api
| if !confirmation_calls.is_empty() { | ||
| debug!("Enclave wants to send {} extrinsics", confirmation_calls.len()); | ||
| for call in confirmation_calls.into_iter() { | ||
| api.send_extrinsic(hex_encode(call.encode()), XtStatus::Ready).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just saw this in the review here: We have some unwraps still in this part of the code. We should probably fix this at some point?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, totally agreed! Does anything speak against fixing it in this PR? 😇
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Time is the reason 😝 For now we have to live with it I think, otherwise I will never be able to get through this refactoring in this sprint 😄 We have many places where we still use unwrap() instead of proper error handling. I think we should fix all of those in one go.
174fc87 to
12743a4
Compare
a0edcd9 to
7468e12
Compare
7468e12 to
0b6cbd9
Compare
0b6cbd9 to
99980a2
Compare
haerdib
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good all in all I think. I left some comments ;)
| confirmations: Vec<u8>, | ||
| signed_blocks: Vec<u8>, | ||
| ) -> OCallBridgeResult<()>; | ||
| fn send_sidechain_blocks(&self, signed_blocks: Vec<u8>) -> OCallBridgeResult<()>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renaming suggestion (@clangenb may correct me here): propose_sidechain_blocks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree, and I think we should actually move the function from another place. The current location was confusing for me. This function gossips the sidechain blocks to peer-validateers now, it has nothing to do with WorkerOnchainBridge.
However, I see now that cleanly separating the sidechain stuff means that we kind of need to replicate some structure from the core-primitives domain into the sidechain domain. This might also be an overkill, so we might just make an extra trait here called SidechainBridge or so?
Finally, @haerdib I think you need to become consistent with your sidechain-block naming. In the teerex pallet, you introduced the calls like propose_sidechainblock. ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will do the re-naming and create a new bridge, called SideChainBridge, to where I'll move that function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, you're right @clangenb . Sorry for that - sidechainblocks it is ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TBH I don't really like propose_sidechainblocks, it's just not how you would write it in English. Sidechain can be a composed noun, but sidechainblock is more like you would form the word in German than in English (where I'd prefer sidechain block)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can agree with both, as long as we stay consistent, I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I guess you could argue that we are in an emerging field, and we henceforth coin the term 'Sidechainblock`, I don't have a strong preference here, but except for the pallet, we have been going with 'sidechain block' until now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets go with _block then. I'll adapt the pallet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For sidechain and parentchain I can agree to have it as a compound noun. But I believe it's very rare in English to have a compound noun made of three words. Otherwise, using your argument, we could also have: parentchainblockconfirmationheader - which is what you would have in German, but definitely not in English
| ) -> OCallBridgeResult<()>; | ||
| fn send_sidechain_blocks(&self, signed_blocks: Vec<u8>) -> OCallBridgeResult<()>; | ||
|
|
||
| fn send_confirmations(&self, confirmations: Vec<u8>) -> OCallBridgeResult<()>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renaming suggestion (@clangenb may correct me here): send_confirmations_to_layer_one or something like that..?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We decided not to use layer_one anymore but rather relative naming as there might be multiple hierarchies, so I'd suggest:
send_to_parentchain(&self, extrinsics_vec_encoded)
The current naming is actually wrong. The 'confirmations' may also contain callbacks from the trustedcall's execution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 I will re-name the function
| if !confirmation_calls.is_empty() { | ||
| debug!("Enclave wants to send {} extrinsics", confirmation_calls.len()); | ||
| for call in confirmation_calls.into_iter() { | ||
| api.send_extrinsic(hex_encode(call.encode()), XtStatus::Ready).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, totally agreed! Does anything speak against fixing it in this PR? 😇
clangenb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comments but looks nice; divide and conquer!
enclave-runtime/src/lib.rs
Outdated
| .send_block_and_confirmation::<SB>(extrinsics, blocks) | ||
| .map_err(|e| Error::Other(format!("Failed to send block and confirmation: {}", e).into())) | ||
| ocall_api.send_confirmations(extrinsics).map_err(|e| { | ||
| Error::Other(format!("Failed to send block and confirmation: {}", e).into()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now, it only sends confirmations, no? :)
| Authority: Pair<Public = sp_core::ed25519::Public>, | ||
| Authority::Public: Encode, | ||
| PB: Block<Hash = H256>, | ||
| SB: SignedBlock<Public = Authority::Public, Signature = MultiSignature> + 'static, | ||
| SB: SignedBlock<Public = sp_core::ed25519::Public, Signature = MultiSignature> + 'static, | ||
| SB::Block: SidechainBlockT<ShardIdentifier = H256, Public = Authority::Public>, | ||
| Authority: Pair<Public = SB::Public>, | ||
| Authority::Public: Encode, | ||
| SB::Signature: From<Authority::Signature>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you invert the relation here? Now we also we have a definition cycle:
Authority: Pair<Public = SB::Public>
SB::Signature: From<Authority::Signature>,
Anyhow, I think the block should not have the MultiSignature in the future but just Authority::Signature, but I could not change that easily when introducing aura ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be consistent, everywhere else we have the authority being defined by the sidechain block public type. Only here it was different, so I changed it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are probably right regarding the definition cycle. So I might have to invert it again, but then do it in all the places where we have these constraint definitions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I see. Good catch in that case! 😄
I think you can leave it until we introduce the change that makes the following possible:
SB: SignedBlock<Public = Authority::Public, Signature = Authority::Signature + 'static,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well now that you mentioned the cyclic definition path, it's bugging me as well. I'll try to change it (and hope I don't shoot myself in the foot with those trait constraints)
| confirmations: Vec<u8>, | ||
| signed_blocks: Vec<u8>, | ||
| ) -> OCallBridgeResult<()>; | ||
| fn send_sidechain_blocks(&self, signed_blocks: Vec<u8>) -> OCallBridgeResult<()>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I agree, and I think we should actually move the function from another place. The current location was confusing for me. This function gossips the sidechain blocks to peer-validateers now, it has nothing to do with WorkerOnchainBridge.
However, I see now that cleanly separating the sidechain stuff means that we kind of need to replicate some structure from the core-primitives domain into the sidechain domain. This might also be an overkill, so we might just make an extra trait here called SidechainBridge or so?
Finally, @haerdib I think you need to become consistent with your sidechain-block naming. In the teerex pallet, you introduced the calls like propose_sidechainblock. ;)
| ) -> OCallBridgeResult<()>; | ||
| fn send_sidechain_blocks(&self, signed_blocks: Vec<u8>) -> OCallBridgeResult<()>; | ||
|
|
||
| fn send_confirmations(&self, confirmations: Vec<u8>) -> OCallBridgeResult<()>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We decided not to use layer_one anymore but rather relative naming as there might be multiple hierarchies, so I'd suggest:
send_to_parentchain(&self, extrinsics_vec_encoded)
The current naming is actually wrong. The 'confirmations' may also contain callbacks from the trustedcall's execution.
…ions This specifically affects the o-call, which is also split now.
extract a separate sidechain bridge from the onchain bridge
472a0e2 to
98451ba
Compare
core-primitives/ocall-api/src/lib.rs
Outdated
| pub trait EnclaveSideChainOCallApi: Clone + Debug + Send + Sync { | ||
| fn propose_sidechain_blocks<SB: Encode>(&self, signed_blocks: Vec<SB>) -> SgxResult<()>; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extraced the propose_sidechain_blocks to a separate trait and ocall bridge everywhere
clangenb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only wondering about case conventions, otherwise it looks very good!
core-primitives/ocall-api/src/lib.rs
Outdated
| ) -> SgxResult<Vec<WorkerResponse<V>>>; | ||
| } | ||
|
|
||
| pub trait EnclaveSideChainOCallApi: Clone + Debug + Send + Sync { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For consistency, the trait should contain Sidechain not SideChain (capital C).
| use itp_ocall_api::{alloc::prelude::v1::Vec, EnclaveSideChainOCallApi}; | ||
| use sgx_types::{sgx_status_t, SgxResult}; | ||
|
|
||
| impl EnclaveSideChainOCallApi for OcallApi { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again the capital 'C'
| @@ -0,0 +1,43 @@ | |||
| /* | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woah, even a separate file. 😄
| #[error("Propose sidechain block failed: {0}")] | ||
| ProposeSideChainBlock(String), | ||
| #[error("Sending extrinsics to parentchain failed: {0}")] | ||
| SendExtrinsicsToParentChain(String), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also the capital 'C'. :)
| use log::*; | ||
| use std::sync::Arc; | ||
|
|
||
| pub struct SideChainOCall<S, D> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I wonder. Did you make it on purpose with the capital 'C's in the CamelCase names? I'd prefer it to be consistent with the snake_case versoin.
|
hmm either I've gone completely crazy, or GitHub does not let me answer to comments anymore, I just have the 'Resolve Conversation' option 😮 |
clangenb
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, I am surprised that we'd have so many SideChains left. Thanks for fixing.
| OCallBridgeError::GetIasSocket(_) => sgx_status_t::SGX_ERROR_UNEXPECTED, | ||
| OCallBridgeError::SendBlockAndConfirmation(_) => sgx_status_t::SGX_ERROR_UNEXPECTED, | ||
| OCallBridgeError::ProposeSidechainBlock(_) => sgx_status_t::SGX_ERROR_UNEXPECTED, | ||
| OCallBridgeError::SendExtrinsicsToParentChain(_) => sgx_status_t::SGX_ERROR_UNEXPECTED, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heh, I also found one :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah parentchain - yes I've only checked for sidechain 😛 another search and replace commit then
haerdib
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only minor comments. Hence, I'm approving.
| match sidechain_api.propose_sidechain_blocks(signed_blocks_vec) { | ||
| Ok(_) => sgx_status_t::SGX_SUCCESS, | ||
| Err(e) => { | ||
| error!("send sidechain blocks failed: {:?}", e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| error!("send sidechain blocks failed: {:?}", e); | |
| error!("Proposing sidechain blocks failed: {:?}", e); |
|
|
||
| fn send_block_and_confirmation( | ||
| fn send_to_parentchain( | ||
| confirmations: *const u8, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
since these have been renamed in woker_on_chain_ocall.rs, should we also rename them to extrinsics_encoded here? Or it that taking it too far?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, you're right - I missed that one when re-naming
| SB: SignedBlockT<Public = sp_core::ed25519::Public, Signature = MultiSignature>, | ||
| SB: SignedBlockT<Public = Signer::Public, Signature = MultiSignature>, | ||
| SB::Block: SidechainBlockT<ShardIdentifier = H256, Public = sp_core::ed25519::Public>, | ||
| SB::Signature: From<Signer::Signature>, | ||
| RpcAuthor: | ||
| AuthorApi<H256, PB::Hash> + SendState<Hash = PB::Hash> + OnBlockCreated<Hash = PB::Hash>, | ||
| StateHandler: QueryShardState, | ||
| StfExecutor: StfExecuteTimedCallsBatch<Externalities = SgxExternalities> | ||
| + StfExecuteGenericUpdate<Externalities = SgxExternalities>, | ||
| Signer: Pair<Public = sp_core::ed25519::Public>, | ||
| Signer::Public: Encode, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed the trait bounds definition now, such that the SignedBlock::Public type is defined by the Signer::Public type
Also re-name the 'confirmations' to 'extrinsics'
This is another refactoring step towards #301.
The goal is to have the functionality that was originally in the
prepare_and_send_xts_and_blockfunction in a separate crate, so that the content ofsidechain_impl.rscan be moved from theenclave_runtimecrate, to thesidechaincrate, where it belongs.As I studied the code, I realized that
prepare_and_send_xts_and_blockdoes 2 things that are not necessarily related:So I separated those 2 functionalities, which resulted in a lot of changes to the O-call API (and all its layers). In addition, I did some refactoring regarding side-effects of those functions. The nonce is now not a
&mutin/out parameter, but just an in-parameter and the mutated nonce value is return in the result. The second side-effect was the signer key pair, that we retrieved in a static method. I now pass this key down as a parameter (which is abstracted by a type parameter).