Conversation
| for parachain in parachains { | ||
| let parachain_head = match Pallet::<T, I>::read_parachain_head(&storage, parachain) { | ||
| Some(parachain_head) => parachain_head, | ||
| None => { |
There was a problem hiding this comment.
Actually it should be supported - parachain may be offboarded and its head may be removed. So there should be 3 possible outcomes from read_parachain_head: Err(_), Ok(Some(_)) and Ok(None). Right now the first (which is relayer error) is replaced with Ok(None), which is handled incorrectly.
There was a problem hiding this comment.
I'd prefer to deal with it in follow-up PRs, as it requires some more thinking + there are already two PRs on top of that one.
| use sp_std::vec::Vec; | ||
|
|
||
| /// Parachain id. | ||
| pub type ParaId = u32; |
There was a problem hiding this comment.
All parachain pallets from Polkadot are using polkadot_parachain::primitives::Id to store parachain id. The difference is that it is compact-encoded u32 => it should be fixed
| pub type ParaId = u32; | ||
|
|
||
| /// Parachain head, which is (at least in Cumulus) a SCALE-encoded parachain header. | ||
| pub type ParaHead = Vec<u8>; |
There was a problem hiding this comment.
Parachains pallet from Polkadot is using polkadot_parachain::primitives::HeadData to store parachain heads. The difference is that they're encoding parachain header twice, i.e. it is prefixed with encoded bytevec length => it should be fixed.
|
@AurevoirXavier @fewensa If you're really keen on this parachain pallets+relay+bridge, then it'll be really helpful if you could add your review to these three dependent PRs - this one, #1199 and #1218 . Please ask any questions directly in PRs (better option) or DM me on riot (you've been already chatting with me there). The most important design question: there are two options to use parachains finality - one is a separate pallet+relay and another one is simply adding parachain head proof to existing proofs. The latter looks simpler - i.e. right now proof of messages looks like |
I don't get this part, do you mean a new parachain_head_storage_proof could be submitted before some message proof get included using relative older parachain header? If that's the case, bridge grandpa pallet may also have similar issue, and onchain cache looks simple and straight forward to me. |
GRANDPA pallet works exactly like this cache :) Let me explain in details. So message proof = So imagine you don't have a bridge GRANDPA pallet in the runtime (let's omit validator set changes for simplicity). Then the messages pallet may still be used, but the message proof changes to That's where GRANDPA pallet helps and where it works like cache - once finality proof is verified, you may just provide header hash in your message proof. and when this proof is verified, you may just read the header from the cache (runtime storage), without reverifying finality proof again. Now imagine you're bridging with parachain and you don't have both GRANDPA pallet and parachains finality pallet. Then the message proof would be Let me know if it makes sense to you. |
eskimor
left a comment
There was a problem hiding this comment.
Looks pretty good as far as I can tell.
| // intersection of `parachains-interesting-to-us` and `parachains` | ||
|
|
||
| // TODO: if some parachain is no more interesting to us, we should start pruning its | ||
| // heads |
There was a problem hiding this comment.
We usually have the rule that each TODO should reference some ticket.
There was a problem hiding this comment.
Yep, thanks - I'll open issues for that
acatangiu
left a comment
There was a problem hiding this comment.
Looks good, just nits and typos 👍
serban300
left a comment
There was a problem hiding this comment.
I tried to ramp-up as a bit on how parachains work and I did multiple iterations on this code. However I still have limited experience with this. But for me, the design looks good. I can't find any issue with it. I just left 2 nits.
|
|
||
| /// Best parachain heads. | ||
| #[pallet::storage] | ||
| pub type BestParaHeads<T: Config<I>, I: 'static = ()> = |
There was a problem hiding this comment.
Nit: Personally I would change this name to something like ParaState or ParaMetaData since it contains more than just the BestParaHeads.
| pub struct BestParaHead { | ||
| /// Number of relay block where this head has been updated. | ||
| pub at_relay_block_number: RelayBlockNumber, | ||
| /// Hash of parachain head. | ||
| pub head_hash: ParaHash, | ||
| /// Current ring buffer position for this parachain. | ||
| pub next_imported_hash_position: u32, | ||
| } |
There was a problem hiding this comment.
Personally I would change this structure to something like:
pub struct ParaState {
pub best_head_hash: BestParaHeadHash,
pub next_imported_hash_position: u32,
}
in order to reuse the BestParaHeadHash structure instead of having 2 structures that contain at_relay_block_number and head_hash.
There was a problem hiding this comment.
Yeah, that's a good idea imo
* BestParaHead small changes Signed-off-by: Serban Iorga <serban@parity.io> * Renamings Signed-off-by: Serban Iorga <serban@parity.io> * Use ParaInfo in parachains loop Signed-off-by: Serban Iorga <serban@parity.io> * Define StorageMapKeyProvider Signed-off-by: Serban Iorga <serban@parity.io> * CR fixes Signed-off-by: Serban Iorga <serban@parity.io>
* parachains finality * parachains pallet test * demo of how to configure GRANDPA pallet instance * allow instances in parachains pallet * spellcheck * TODO + fix * fmt * removed invalid storage_keys file * change all hashers to Blake2_128Concat * use Twox64Concat for insertion position * fix build * fix compilation * change ParaId and ParaHead types * TODOs -> TODOs with issues refs
* BestParaHead small changes Signed-off-by: Serban Iorga <serban@parity.io> * Renamings Signed-off-by: Serban Iorga <serban@parity.io> * Use ParaInfo in parachains loop Signed-off-by: Serban Iorga <serban@parity.io> * Define StorageMapKeyProvider Signed-off-by: Serban Iorga <serban@parity.io> * CR fixes Signed-off-by: Serban Iorga <serban@parity.io>
* parachains finality * parachains pallet test * demo of how to configure GRANDPA pallet instance * allow instances in parachains pallet * spellcheck * TODO + fix * fmt * removed invalid storage_keys file * change all hashers to Blake2_128Concat * use Twox64Concat for insertion position * fix build * fix compilation * change ParaId and ParaHead types * TODOs -> TODOs with issues refs
* BestParaHead small changes Signed-off-by: Serban Iorga <serban@parity.io> * Renamings Signed-off-by: Serban Iorga <serban@parity.io> * Use ParaInfo in parachains loop Signed-off-by: Serban Iorga <serban@parity.io> * Define StorageMapKeyProvider Signed-off-by: Serban Iorga <serban@parity.io> * CR fixes Signed-off-by: Serban Iorga <serban@parity.io>
I've been considering generic pallet that'll e able to solve both parachains finality + #1002 (comment) . That's because both pallets are simple receiving storage proof => parsing proof => optionally check that the proof is duplicate => doing some actions, based on this proof. But the generic palle will be too generic - imo it is better to have parachains finality logic separated from some generic code.
This is very WIP, although current code already gives general idea of what it'll look like. Main questions that still needs to be solved is keeping old parachain headers (aka heads) as we do with relay chain headers + add similar pruning.