-
Notifications
You must be signed in to change notification settings - Fork 2.7k
BEEFY-specific import_justification #10699
Conversation
|
you beauty 😍 |
… david/beefy-block-import
… david/beefy-block-import
client/beefy/Cargo.toml
Outdated
| sc-keystore = { version = "4.0.0-dev", path = "../keystore" } | ||
| sc-network = { version = "0.10.0-dev", path = "../network" } | ||
| sc-network-gossip = { version = "0.10.0-dev", path = "../network-gossip" } | ||
| sp-consensus = { version = "0.10.0-dev", path = "../../primitives/consensus/common" } |
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.
nit:
please move this above with the other sp-* and ideally keep alphabetical ordering for easy reading/parsing
client/beefy/src/lib.rs
Outdated
| /// Link between the block importer and the beefy client. | ||
| /// It provides access to the justification stream | ||
| pub struct LinkHalf<Block: BlockT> { | ||
| justification_stream: BeefyJustificationStream<NumberFor<Block>, Signature>, | ||
| } | ||
|
|
||
| impl<Block: BlockT> LinkHalf<Block> { | ||
| /// Get the receiving end of justification notifications. | ||
| pub fn justification_stream(&self) -> BeefyJustificationStream<NumberFor<Block>, Signature> { | ||
| self.justification_stream.clone() | ||
| } | ||
| } |
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.
can't this be a simple type definition?
| /// Link between the block importer and the beefy client. | |
| /// It provides access to the justification stream | |
| pub struct LinkHalf<Block: BlockT> { | |
| justification_stream: BeefyJustificationStream<NumberFor<Block>, Signature>, | |
| } | |
| impl<Block: BlockT> LinkHalf<Block> { | |
| /// Get the receiving end of justification notifications. | |
| pub fn justification_stream(&self) -> BeefyJustificationStream<NumberFor<Block>, Signature> { | |
| self.justification_stream.clone() | |
| } | |
| } | |
| /// Link between the block importer and the beefy client, the justification stream. | |
| pub type LinkHalf<Block> = BeefyJustificationStream<NumberFor<Block>, Signature>; |
or (even better) just use BeefyJustificationStream directly for clarity.
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.
Okay, I reasoned we might share more state between the block import worker and the beefy worker in the future like in grandpa, that's why I created this struct, I guess the just the justification stream is good for now though.
client/beefy/src/lib.rs
Outdated
| ) -> (BeefyBlockImport<BE, Block, Client, I>, LinkHalf<Block>) { | ||
| let (justification_sender, justification_stream) = BeefyJustificationStream::channel(); | ||
| let import = | ||
| BeefyBlockImport::new(client.clone(), wrapped_block_import, justification_sender.clone()); |
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.
| BeefyBlockImport::new(client.clone(), wrapped_block_import, justification_sender.clone()); | |
| BeefyBlockImport::new(client.clone(), wrapped_block_import, justification_sender); |
| /// Produce a BEEFY block import object and a link half for tying it to the client | ||
| pub fn block_import<BE, Client, Block: BlockT, I>( |
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.
Pls add a companion PR that uses this in Polkadot (Rococo chain).
| #[async_trait::async_trait] | ||
| impl<BE, Block: BlockT, Client, I> JustificationImport<Block> | ||
| for BeefyBlockImport<BE, Block, Client, I> | ||
| where | ||
| BE: Backend<Block>, | ||
| Client: BeefyClient<Block, BE> + ProvideRuntimeApi<Block>, | ||
| Client::Api: BeefyApi<Block>, | ||
| I: JustificationImport<Block, Error = ConsensusError> + Send + Sync, | ||
| { | ||
| type Error = ConsensusError; | ||
|
|
||
| async fn on_start(&mut self) -> Vec<(Block::Hash, NumberFor<Block>)> { | ||
| self.inner.on_start().await | ||
| } | ||
|
|
||
| async fn import_justification( | ||
| &mut self, | ||
| hash: Block::Hash, | ||
| number: NumberFor<Block>, | ||
| justification: Justification, | ||
| ) -> Result<(), Self::Error> { | ||
| // Try Importing Beefy justification | ||
| BeefyBlockImport::import_justification(self, hash, number, justification.clone())?; | ||
| // Importing for inner BlockImport | ||
| self.inner.import_justification(hash, number, justification).await | ||
| } | ||
| } |
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.
Where would this be used? As I understand it, we're manually importing justifications on BlockImport.
Is JustificationImport::import_justification ever going to be called for beefy justifications? If yes, where from (I'm new to this area myself)?
client/beefy/src/justification.rs
Outdated
| let res = verify_with_validator_set::<Block>(number, validator_set, finality_proof.clone())?; | ||
|
|
||
| if res { | ||
| return Ok(finality_proof) | ||
| } | ||
|
|
||
| Err(ConsensusError::InvalidJustification) |
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.
nit:
| let res = verify_with_validator_set::<Block>(number, validator_set, finality_proof.clone())?; | |
| if res { | |
| return Ok(finality_proof) | |
| } | |
| Err(ConsensusError::InvalidJustification) | |
| if verify_with_validator_set::<Block>(number, validator_set, finality_proof.clone())? { | |
| Ok(finality_proof) | |
| } else { | |
| Err(ConsensusError::InvalidJustification) | |
| } |
client/beefy/src/import.rs
Outdated
| /// BeefyBlockImport | ||
| /// Wraps a type `inner` that implements [`BlockImport`] |
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.
| /// BeefyBlockImport | |
| /// Wraps a type `inner` that implements [`BlockImport`] | |
| /// A block-import handler for BEEFY. | |
| /// | |
| /// This scans each imported block for BEEFY justifications and verifies them. | |
| /// Wraps a type `inner` that implements [`BlockImport`] and ultimately defers to it. |
client/beefy/src/import.rs
Outdated
|
|
||
| /// Checks the given header for a consensus digest signalling a beefy authority set change | ||
| /// and extracts it. | ||
| pub fn find_beefy_authority_set_change<B: BlockT>( |
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.
no reason for this helper fn to be public
| pub fn find_beefy_authority_set_change<B: BlockT>( | |
| fn find_beefy_authority_set_change<B: BlockT>( |
| pub struct BeefyBlockImport<Backend, Block: BlockT, Client, I> { | ||
| client: Arc<Client>, | ||
| inner: I, | ||
| justification_sender: BeefyJustificationSender<NumberFor<Block>, 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.
Oh, and I'd forgot about this, sorry.
The code in the PR only validates BEEFY justifications in block imports and nothing else.
I am guessing there is a 2nd part or a future PR that uses this justification_sender to forward justifications from block import to the beefy gadget, right?
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.
Yeah, there should definitely be a second PR that makes use of this , but I don't understand fully how it would look like, was hoping to get insight on that after this was reviewed, but this just verifies beefy justfications if present and ensures there are justifications for authority set change blocks.
… david/beefy-block-import
tomusdrw
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.
The PR makes many low-level design/architectural decisions that I feel were not well thought through or discussed with the responsible team, also some of that stuff is just incorrect. IMHO there is too much to change here to be worth continuing this discussion as a PR review.
I appreciate your willingness to help and note that this is mostly failure on our side, since the design docs and proper issue details are missing.
Please consult a working draft of BEEFY spec & implementation notes for now and until the docs are fully fleshed-out the best way forward is to discuss implementation details of a particular issue with the responsible team beforehand.
| // If this block contains a beefy authority set change then it must have a beefy | ||
| // justification | ||
| let change = find_beefy_authority_set_change::<Block>(&block.header); |
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.
What is this assumption based on?
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.
This was based on the mandatory blocks requirement in the docs
| let id = OpaqueDigestItemId::Consensus(&BEEFY_ENGINE_ID); | ||
|
|
||
| let filter_log = |log: ConsensusLog<AuthorityId>| match log { | ||
| ConsensusLog::AuthoritiesChange(change) => Some(change), |
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.
This logic is duplicated in gadget code.
| @@ -0,0 +1,197 @@ | |||
| use std::{collections::HashMap, marker::PhantomData, sync::Arc}; | |||
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.
No preamble
| let validator_set = self | ||
| .client | ||
| .runtime_api() | ||
| .validator_set(&at) | ||
| .map_err(|e| ConsensusError::ClientImport(e.to_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.
We should be verifying that the previous authority set has signed off on the hand-off instead.
| @@ -0,0 +1,58 @@ | |||
| use crate::keystore::BeefyKeystore; | |||
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.
Preamble missing.
| pub(crate) fn verify_with_validator_set<Block: BlockT>( | ||
| number: NumberFor<Block>, | ||
| validator_set: &ValidatorSet<AuthorityId>, | ||
| proof: VersionedFinalityProof<NumberFor<Block>, Signature>, | ||
| ) -> Result<bool, ConsensusError> { |
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.
This logic should most likely be part of the gadget code not hardcoded into client/beefy
| cfg | ||
| } | ||
|
|
||
| /// Produce a BEEFY block import object and a link half for tying it to the client |
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.
This is misleading. The gadget will be appending justifications as well and notifications will not be triggered here.
@tomusdrw could you please help detail how this issue could be solved correctly? I’ll really like to get it across the finish line. |
|
Hey, is anyone still working on this? Due to the inactivity this issue has been automatically marked as stale. It will be closed if no further activity occurs. Thank you for your contributions. |
|
Bump |
|
Hey, is anyone still working on this? Due to the inactivity this issue has been automatically marked as stale. It will be closed if no further activity occurs. Thank you for your contributions. |
|
bump |
|
Hey, is anyone still working on this? Due to the inactivity this issue has been automatically marked as stale. It will be closed if no further activity occurs. Thank you for your contributions. |
|
We need to settle on a design first (paritytech/grandpa-bridge-gadget#183 (comment)). Closing this for now. |
Fixes paritytech/grandpa-bridge-gadget#183
polkadot companion: paritytech/polkadot#4791