Verify Grandpa proofs from within runtime#4167
Verify Grandpa proofs from within runtime#4167HCastano wants to merge 34 commits intoparitytech:hc-jp-bridge-modulefrom
Conversation
…tytech#3874) * Make tests work after the changes introduced in paritytech#3793 * Remove unneccessary import
…ytech#3915) * Make StorageProofChecker happy * Update some tests * Check given validator set against set found in storage * Use Finality Grandpa's Authority Id and Weight * Add better error handling * Use error type from decl_error! macro
* Create module for checking ancestry proofs * Use Vec of Headers instead of a HashMap * Move the ancestry verification into the lib.rs file * Change the proof format to exclude `child` and `ancestor` headers * Add a testing function for building header chains * Rename AncestorNotFound error to InvalidAncestryProof * Use ancestor hash instead of header when verifying ancestry * Clean up some stuff missed in the merge
This comment has been minimized.
This comment has been minimized.
|
As @svyatonik pointed out to me, not all the functions are needed by the bridge module (e.g |
| /// This is meant to be stored in the db and passed around the network to other | ||
| /// nodes, and are used by syncing nodes to prove authority set handoffs. | ||
| #[derive(Encode, Decode)] | ||
| pub struct GrandpaJustification<Block: BlockT> { |
There was a problem hiding this comment.
I feel like the contents of this module should be in the palette/grandpa crate, since it's generally useful.
There was a problem hiding this comment.
IMO it should go into primitives/finality-grandpa and then it gets used by both client and pallet code (and also by the bridge pallet).
There was a problem hiding this comment.
I'm going to wait until I rebase past the-big-reorg before moving the code into primitives/finality-grandpa.
andresilva
left a comment
There was a problem hiding this comment.
I think migrating to BTrees is sensible, we just did the same thing on the finality-grandpa crate.
| if as_public.verify(&encoded_raw, signature) { | ||
| Ok(()) | ||
| } else { | ||
| // debug!(target: "afg", "Bad signature on message from {:?}", id); |
There was a problem hiding this comment.
We probably want to keep this for the client code that uses it once this is refactored to re-use the same code.
|
There are a couple of things that I want to do in later PRs:
I think it's fine to get this PR in without these two things. Once this is merged I can then go ahead and rebase the whole bridge branch past |
jimpo
left a comment
There was a problem hiding this comment.
Just did a very cursory review as you need to drop some disallowed dependencies which show up in a bunch of places.
| [dependencies] | ||
| codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false } | ||
| client = { package = "substrate-client", path = "../../core/client" } | ||
| fg = { package = "substrate-finality-grandpa", path = "../../core/finality-grandpa/" } |
There was a problem hiding this comment.
I'm gonna wait on #3868 before getting rid of it
|
I think it's going to be a little annoying to get rid of the |
|
I think some of the |
|
|
||
| use codec::{Encode, Decode}; | ||
| use core::cmp::{Ord, Ordering}; | ||
| // TODO: Since I can't use types from `core/finality-grandpa`, wait until #3868 |
There was a problem hiding this comment.
Put this TODO in the Cargo.toml too, which is more important.
| /// targets should be the same as the commit target, since honest voters don't | ||
| /// vote past authority set change blocks. | ||
| /// | ||
| /// This is meant to be stored in the db and passed around the network to other |
There was a problem hiding this comment.
This part of the comment seems wrong (stored in the db and networked).
| /// Create a GRANDPA justification from the given commit. This method | ||
| /// assumes the commit is valid and well-formed. | ||
| #[cfg(test)] | ||
| pub(crate) fn from_commit<B, E, RA>( |
There was a problem hiding this comment.
nit: Just make it pub, not pub(crate). The module is private.
| let mut votes_ancestries_hashes = BTreeSet::new(); | ||
| let mut votes_ancestries = Vec::new(); | ||
|
|
||
| let error = || { |
|
|
||
| /// Decode a GRANDPA justification and validate the commit and the votes' | ||
| /// ancestry proofs finalize the given block. | ||
| pub(crate) fn decode_and_verify_finalizes( |
| } | ||
|
|
||
| #[cfg_attr(test, derive(Debug))] | ||
| pub(crate) enum JustificationError { |
There was a problem hiding this comment.
You can get rid of this. Just use the normal error type. Any function that returns Result<(), JustificationError> where the error is always BadJustification (like from_commit and verify) can return an error type of ().
|
|
||
| impl<Block: BlockT> AncestryChain<Block> { | ||
| fn new(ancestry: &[Block::Header]) -> AncestryChain<Block> { | ||
| let ancestry: BTreeMap<_, _> = ancestry |
There was a problem hiding this comment.
nit: this type hint shouldn't be necessary.
| /// This is useful when validating commits, using the given set of headers to | ||
| /// verify a valid ancestry route to the target commit block. | ||
| struct AncestryChain<Block: BlockT> { | ||
| ancestry: BTreeMap<BlockHashKey<Block>, Block::Header>, |
There was a problem hiding this comment.
Perhaps not necessary, but this could be a BTreeMap<BlockHashKey<Block>, &'a Block::Header> (map to header refs to avoid cloning).
| ); | ||
| } | ||
|
|
||
| // Currently stealing this from `core/finality-grandpa/src/test.rs` |
There was a problem hiding this comment.
Do you expect it to be replaced? Otherwise, don't say "Currently".
|
|
||
| use crate::Error; | ||
|
|
||
| pub(crate) type StorageProof = Vec<Vec<u8>>; |
|
I talked with Jim about some of the options for moving this forward. Since there's a lot of code that came from
We think that the best way forward is (2) as it'll allow us to have a cleaner implementation that doesn't duplicate Grandpa code. |
50c6a2f to
4f7397d
Compare
296d8a4 to
2064106
Compare
|
Closing in favour of paritytech/parity-bridges-common#19. |
I'm looking to get some feedback on this. For the bridge module, we need to be able to verify the validity of Grandpa proofs. The problem is however, that there is no way to do this from within the runtime as the current Grandpa proof code requires
std. What I've done here is taken some of the code from the Substratefinality-grandpacrate and modified it to make it work in ano_stdenvironment. The two main changes were:HashMapandHashSettoBTreeMapandBTreeSetAuthorityPairfor signature verification, to usingAuthoritySignature+RuntimeAppPublicIdeally this code wouldn't be duplicated in two places, but right now I'm just trying to make this work in the context of the bridge module.
Before merging this PR I'd like to have the
submit_finalized_headers()function actually using the new code to verify Grandpa proofs.