Beefy: use VersionedFinalityProof instead of SignedCommitment (#11962)

* beefy: use VersionedFinalityProof instead of SignedCommitment.

* Change the exposed RPC API to support versioned proofs.

Co-authored-by: Adrian Catangiu <adrian@parity.io>
This commit is contained in:
ZhiYong
2022-08-04 15:47:52 +08:00
committed by GitHub
parent 97b2a5ee75
commit b8ad45373f
8 changed files with 157 additions and 140 deletions
+26 -25
View File
@@ -35,7 +35,7 @@ use jsonrpsee::{
}; };
use log::warn; use log::warn;
use beefy_gadget::notification::{BeefyBestBlockStream, BeefySignedCommitmentStream}; use beefy_gadget::notification::{BeefyBestBlockStream, BeefyVersionedFinalityProofStream};
mod notification; mod notification;
@@ -101,7 +101,7 @@ pub trait BeefyApi<Notification, Hash> {
/// Implements the BeefyApi RPC trait for interacting with BEEFY. /// Implements the BeefyApi RPC trait for interacting with BEEFY.
pub struct Beefy<Block: BlockT> { pub struct Beefy<Block: BlockT> {
signed_commitment_stream: BeefySignedCommitmentStream<Block>, finality_proof_stream: BeefyVersionedFinalityProofStream<Block>,
beefy_best_block: Arc<RwLock<Option<Block::Hash>>>, beefy_best_block: Arc<RwLock<Option<Block::Hash>>>,
executor: SubscriptionTaskExecutor, executor: SubscriptionTaskExecutor,
} }
@@ -112,7 +112,7 @@ where
{ {
/// Creates a new Beefy Rpc handler instance. /// Creates a new Beefy Rpc handler instance.
pub fn new( pub fn new(
signed_commitment_stream: BeefySignedCommitmentStream<Block>, finality_proof_stream: BeefyVersionedFinalityProofStream<Block>,
best_block_stream: BeefyBestBlockStream<Block>, best_block_stream: BeefyBestBlockStream<Block>,
executor: SubscriptionTaskExecutor, executor: SubscriptionTaskExecutor,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
@@ -126,20 +126,21 @@ where
}); });
executor.spawn("substrate-rpc-subscription", Some("rpc"), future.map(drop).boxed()); executor.spawn("substrate-rpc-subscription", Some("rpc"), future.map(drop).boxed());
Ok(Self { signed_commitment_stream, beefy_best_block, executor }) Ok(Self { finality_proof_stream, beefy_best_block, executor })
} }
} }
#[async_trait] #[async_trait]
impl<Block> BeefyApiServer<notification::EncodedSignedCommitment, Block::Hash> for Beefy<Block> impl<Block> BeefyApiServer<notification::EncodedVersionedFinalityProof, Block::Hash>
for Beefy<Block>
where where
Block: BlockT, Block: BlockT,
{ {
fn subscribe_justifications(&self, mut sink: SubscriptionSink) -> SubscriptionResult { fn subscribe_justifications(&self, mut sink: SubscriptionSink) -> SubscriptionResult {
let stream = self let stream = self
.signed_commitment_stream .finality_proof_stream
.subscribe() .subscribe()
.map(|sc| notification::EncodedSignedCommitment::new::<Block>(sc)); .map(|vfp| notification::EncodedVersionedFinalityProof::new::<Block>(vfp));
let fut = async move { let fut = async move {
sink.pipe_from_stream(stream).await; sink.pipe_from_stream(stream).await;
@@ -164,31 +165,31 @@ mod tests {
use super::*; use super::*;
use beefy_gadget::{ use beefy_gadget::{
justification::BeefySignedCommitment, justification::BeefyVersionedFinalityProof,
notification::{BeefyBestBlockStream, BeefySignedCommitmentSender}, notification::{BeefyBestBlockStream, BeefyVersionedFinalityProofSender},
}; };
use beefy_primitives::{known_payload_ids, Payload}; use beefy_primitives::{known_payload_ids, Payload, SignedCommitment};
use codec::{Decode, Encode}; use codec::{Decode, Encode};
use jsonrpsee::{types::EmptyParams, RpcModule}; use jsonrpsee::{types::EmptyParams, RpcModule};
use sp_runtime::traits::{BlakeTwo256, Hash}; use sp_runtime::traits::{BlakeTwo256, Hash};
use substrate_test_runtime_client::runtime::Block; use substrate_test_runtime_client::runtime::Block;
fn setup_io_handler() -> (RpcModule<Beefy<Block>>, BeefySignedCommitmentSender<Block>) { fn setup_io_handler() -> (RpcModule<Beefy<Block>>, BeefyVersionedFinalityProofSender<Block>) {
let (_, stream) = BeefyBestBlockStream::<Block>::channel(); let (_, stream) = BeefyBestBlockStream::<Block>::channel();
setup_io_handler_with_best_block_stream(stream) setup_io_handler_with_best_block_stream(stream)
} }
fn setup_io_handler_with_best_block_stream( fn setup_io_handler_with_best_block_stream(
best_block_stream: BeefyBestBlockStream<Block>, best_block_stream: BeefyBestBlockStream<Block>,
) -> (RpcModule<Beefy<Block>>, BeefySignedCommitmentSender<Block>) { ) -> (RpcModule<Beefy<Block>>, BeefyVersionedFinalityProofSender<Block>) {
let (commitment_sender, commitment_stream) = let (finality_proof_sender, finality_proof_stream) =
BeefySignedCommitmentStream::<Block>::channel(); BeefyVersionedFinalityProofStream::<Block>::channel();
let handler = let handler =
Beefy::new(commitment_stream, best_block_stream, sc_rpc::testing::test_executor()) Beefy::new(finality_proof_stream, best_block_stream, sc_rpc::testing::test_executor())
.expect("Setting up the BEEFY RPC handler works"); .expect("Setting up the BEEFY RPC handler works");
(handler.into_rpc(), commitment_sender) (handler.into_rpc(), finality_proof_sender)
} }
#[tokio::test] #[tokio::test]
@@ -262,21 +263,21 @@ mod tests {
assert_eq!(response.result, expected); assert_eq!(response.result, expected);
} }
fn create_commitment() -> BeefySignedCommitment<Block> { fn create_finality_proof() -> BeefyVersionedFinalityProof<Block> {
let payload = Payload::new(known_payload_ids::MMR_ROOT_ID, "Hello World!".encode()); let payload = Payload::new(known_payload_ids::MMR_ROOT_ID, "Hello World!".encode());
BeefySignedCommitment::<Block> { BeefyVersionedFinalityProof::<Block>::V1(SignedCommitment {
commitment: beefy_primitives::Commitment { commitment: beefy_primitives::Commitment {
payload, payload,
block_number: 5, block_number: 5,
validator_set_id: 0, validator_set_id: 0,
}, },
signatures: vec![], signatures: vec![],
} })
} }
#[tokio::test] #[tokio::test]
async fn subscribe_and_listen_to_one_justification() { async fn subscribe_and_listen_to_one_justification() {
let (rpc, commitment_sender) = setup_io_handler(); let (rpc, finality_proof_sender) = setup_io_handler();
// Subscribe // Subscribe
let mut sub = rpc let mut sub = rpc
@@ -284,16 +285,16 @@ mod tests {
.await .await
.unwrap(); .unwrap();
// Notify with commitment // Notify with finality_proof
let commitment = create_commitment(); let finality_proof = create_finality_proof();
let r: Result<(), ()> = commitment_sender.notify(|| Ok(commitment.clone())); let r: Result<(), ()> = finality_proof_sender.notify(|| Ok(finality_proof.clone()));
r.unwrap(); r.unwrap();
// Inspect what we received // Inspect what we received
let (bytes, recv_sub_id) = sub.next::<sp_core::Bytes>().await.unwrap().unwrap(); let (bytes, recv_sub_id) = sub.next::<sp_core::Bytes>().await.unwrap().unwrap();
let recv_commitment: BeefySignedCommitment<Block> = let recv_finality_proof: BeefyVersionedFinalityProof<Block> =
Decode::decode(&mut &bytes[..]).unwrap(); Decode::decode(&mut &bytes[..]).unwrap();
assert_eq!(&recv_sub_id, sub.subscription_id()); assert_eq!(&recv_sub_id, sub.subscription_id());
assert_eq!(recv_commitment, commitment); assert_eq!(recv_finality_proof, finality_proof);
} }
} }
@@ -21,19 +21,19 @@ use serde::{Deserialize, Serialize};
use sp_runtime::traits::Block as BlockT; use sp_runtime::traits::Block as BlockT;
/// An encoded signed commitment proving that the given header has been finalized. /// An encoded finality proof proving that the given header has been finalized.
/// The given bytes should be the SCALE-encoded representation of a /// The given bytes should be the SCALE-encoded representation of a
/// `beefy_primitives::SignedCommitment`. /// `beefy_primitives::VersionedFinalityProof`.
#[derive(Clone, Serialize, Deserialize)] #[derive(Clone, Serialize, Deserialize)]
pub struct EncodedSignedCommitment(sp_core::Bytes); pub struct EncodedVersionedFinalityProof(sp_core::Bytes);
impl EncodedSignedCommitment { impl EncodedVersionedFinalityProof {
pub fn new<Block>( pub fn new<Block>(
signed_commitment: beefy_gadget::justification::BeefySignedCommitment<Block>, finality_proof: beefy_gadget::justification::BeefyVersionedFinalityProof<Block>,
) -> Self ) -> Self
where where
Block: BlockT, Block: BlockT,
{ {
EncodedSignedCommitment(signed_commitment.encode().into()) EncodedVersionedFinalityProof(finality_proof.encode().into())
} }
} }
+11 -15
View File
@@ -16,7 +16,7 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
use beefy_primitives::{crypto::Signature, BeefyApi, VersionedFinalityProof, BEEFY_ENGINE_ID}; use beefy_primitives::{BeefyApi, BEEFY_ENGINE_ID};
use codec::Encode; use codec::Encode;
use log::error; use log::error;
use std::{collections::HashMap, sync::Arc}; use std::{collections::HashMap, sync::Arc};
@@ -34,7 +34,8 @@ use sc_client_api::backend::Backend;
use sc_consensus::{BlockCheckParams, BlockImport, BlockImportParams, ImportResult}; use sc_consensus::{BlockCheckParams, BlockImport, BlockImportParams, ImportResult};
use crate::{ use crate::{
justification::decode_and_verify_commitment, notification::BeefySignedCommitmentSender, justification::{decode_and_verify_finality_proof, BeefyVersionedFinalityProof},
notification::BeefyVersionedFinalityProofSender,
}; };
/// A block-import handler for BEEFY. /// A block-import handler for BEEFY.
@@ -47,7 +48,7 @@ pub struct BeefyBlockImport<Block: BlockT, Backend, RuntimeApi, I> {
backend: Arc<Backend>, backend: Arc<Backend>,
runtime: Arc<RuntimeApi>, runtime: Arc<RuntimeApi>,
inner: I, inner: I,
justification_sender: BeefySignedCommitmentSender<Block>, justification_sender: BeefyVersionedFinalityProofSender<Block>,
} }
impl<Block: BlockT, BE, Runtime, I: Clone> Clone for BeefyBlockImport<Block, BE, Runtime, I> { impl<Block: BlockT, BE, Runtime, I: Clone> Clone for BeefyBlockImport<Block, BE, Runtime, I> {
@@ -67,7 +68,7 @@ impl<Block: BlockT, BE, Runtime, I> BeefyBlockImport<Block, BE, Runtime, I> {
backend: Arc<BE>, backend: Arc<BE>,
runtime: Arc<Runtime>, runtime: Arc<Runtime>,
inner: I, inner: I,
justification_sender: BeefySignedCommitmentSender<Block>, justification_sender: BeefyVersionedFinalityProofSender<Block>,
) -> BeefyBlockImport<Block, BE, Runtime, I> { ) -> BeefyBlockImport<Block, BE, Runtime, I> {
BeefyBlockImport { backend, runtime, inner, justification_sender } BeefyBlockImport { backend, runtime, inner, justification_sender }
} }
@@ -85,7 +86,7 @@ where
encoded: &EncodedJustification, encoded: &EncodedJustification,
number: NumberFor<Block>, number: NumberFor<Block>,
hash: <Block as BlockT>::Hash, hash: <Block as BlockT>::Hash,
) -> Result<VersionedFinalityProof<NumberFor<Block>, Signature>, ConsensusError> { ) -> Result<BeefyVersionedFinalityProof<Block>, ConsensusError> {
let block_id = BlockId::hash(hash); let block_id = BlockId::hash(hash);
let validator_set = self let validator_set = self
.runtime .runtime
@@ -94,7 +95,7 @@ where
.map_err(|e| ConsensusError::ClientImport(e.to_string()))? .map_err(|e| ConsensusError::ClientImport(e.to_string()))?
.ok_or_else(|| ConsensusError::ClientImport("Unknown validator set".to_string()))?; .ok_or_else(|| ConsensusError::ClientImport("Unknown validator set".to_string()))?;
decode_and_verify_commitment::<Block>(&encoded[..], number, &validator_set) decode_and_verify_finality_proof::<Block>(&encoded[..], number, &validator_set)
} }
/// Import BEEFY justification: Send it to worker for processing and also append it to backend. /// Import BEEFY justification: Send it to worker for processing and also append it to backend.
@@ -105,7 +106,7 @@ where
fn import_beefy_justification_unchecked( fn import_beefy_justification_unchecked(
&self, &self,
number: NumberFor<Block>, number: NumberFor<Block>,
justification: VersionedFinalityProof<NumberFor<Block>, Signature>, justification: BeefyVersionedFinalityProof<Block>,
) { ) {
// Append the justification to the block in the backend. // Append the justification to the block in the backend.
if let Err(e) = self.backend.append_justification( if let Err(e) = self.backend.append_justification(
@@ -115,14 +116,9 @@ where
error!(target: "beefy", "🥩 Error {:?} on appending justification: {:?}", e, justification); error!(target: "beefy", "🥩 Error {:?} on appending justification: {:?}", e, justification);
} }
// Send the justification to the BEEFY voter for processing. // Send the justification to the BEEFY voter for processing.
match justification { self.justification_sender
// TODO #11838: Should not unpack, these channels should also use .notify(|| Ok::<_, ()>(justification))
// `VersionedFinalityProof`. .expect("forwards closure result; the closure always returns Ok; qed.");
VersionedFinalityProof::V1(signed_commitment) => self
.justification_sender
.notify(|| Ok::<_, ()>(signed_commitment))
.expect("forwards closure result; the closure always returns Ok; qed."),
};
} }
} }
+32 -21
View File
@@ -25,17 +25,17 @@ use codec::{Decode, Encode};
use sp_consensus::Error as ConsensusError; use sp_consensus::Error as ConsensusError;
use sp_runtime::traits::{Block as BlockT, NumberFor}; use sp_runtime::traits::{Block as BlockT, NumberFor};
/// A commitment with matching BEEFY authorities' signatures. /// A finality proof with matching BEEFY authorities' signatures.
pub type BeefySignedCommitment<Block> = pub type BeefyVersionedFinalityProof<Block> =
beefy_primitives::SignedCommitment<NumberFor<Block>, beefy_primitives::crypto::Signature>; beefy_primitives::VersionedFinalityProof<NumberFor<Block>, Signature>;
/// Decode and verify a Beefy SignedCommitment. /// Decode and verify a Beefy FinalityProof.
pub(crate) fn decode_and_verify_commitment<Block: BlockT>( pub(crate) fn decode_and_verify_finality_proof<Block: BlockT>(
encoded: &[u8], encoded: &[u8],
target_number: NumberFor<Block>, target_number: NumberFor<Block>,
validator_set: &ValidatorSet<AuthorityId>, validator_set: &ValidatorSet<AuthorityId>,
) -> Result<VersionedFinalityProof<NumberFor<Block>, Signature>, ConsensusError> { ) -> Result<BeefyVersionedFinalityProof<Block>, ConsensusError> {
let proof = <VersionedFinalityProof<NumberFor<Block>, Signature>>::decode(&mut &*encoded) let proof = <BeefyVersionedFinalityProof<Block>>::decode(&mut &*encoded)
.map_err(|_| ConsensusError::InvalidJustification)?; .map_err(|_| ConsensusError::InvalidJustification)?;
verify_with_validator_set::<Block>(target_number, validator_set, &proof).map(|_| proof) verify_with_validator_set::<Block>(target_number, validator_set, &proof).map(|_| proof)
} }
@@ -44,7 +44,7 @@ pub(crate) fn decode_and_verify_commitment<Block: BlockT>(
fn verify_with_validator_set<Block: BlockT>( fn verify_with_validator_set<Block: BlockT>(
target_number: NumberFor<Block>, target_number: NumberFor<Block>,
validator_set: &ValidatorSet<AuthorityId>, validator_set: &ValidatorSet<AuthorityId>,
proof: &VersionedFinalityProof<NumberFor<Block>, Signature>, proof: &BeefyVersionedFinalityProof<Block>,
) -> Result<(), ConsensusError> { ) -> Result<(), ConsensusError> {
match proof { match proof {
VersionedFinalityProof::V1(signed_commitment) => { VersionedFinalityProof::V1(signed_commitment) => {
@@ -80,17 +80,19 @@ fn verify_with_validator_set<Block: BlockT>(
#[cfg(test)] #[cfg(test)]
pub(crate) mod tests { pub(crate) mod tests {
use beefy_primitives::{known_payload_ids, Commitment, Payload, SignedCommitment}; use beefy_primitives::{
known_payload_ids, Commitment, Payload, SignedCommitment, VersionedFinalityProof,
};
use substrate_test_runtime_client::runtime::Block; use substrate_test_runtime_client::runtime::Block;
use super::*; use super::*;
use crate::{keystore::tests::Keyring, tests::make_beefy_ids}; use crate::{keystore::tests::Keyring, tests::make_beefy_ids};
pub(crate) fn new_signed_commitment( pub(crate) fn new_finality_proof(
block_num: NumberFor<Block>, block_num: NumberFor<Block>,
validator_set: &ValidatorSet<AuthorityId>, validator_set: &ValidatorSet<AuthorityId>,
keys: &[Keyring], keys: &[Keyring],
) -> BeefySignedCommitment<Block> { ) -> BeefyVersionedFinalityProof<Block> {
let commitment = Commitment { let commitment = Commitment {
payload: Payload::new(known_payload_ids::MMR_ROOT_ID, vec![]), payload: Payload::new(known_payload_ids::MMR_ROOT_ID, vec![]),
block_number: block_num, block_number: block_num,
@@ -98,7 +100,7 @@ pub(crate) mod tests {
}; };
let message = commitment.encode(); let message = commitment.encode();
let signatures = keys.iter().map(|key| Some(key.sign(&message))).collect(); let signatures = keys.iter().map(|key| Some(key.sign(&message))).collect();
SignedCommitment { commitment, signatures } VersionedFinalityProof::V1(SignedCommitment { commitment, signatures })
} }
#[test] #[test]
@@ -108,7 +110,7 @@ pub(crate) mod tests {
// build valid justification // build valid justification
let block_num = 42; let block_num = 42;
let proof = new_signed_commitment(block_num, &validator_set, keys); let proof = new_finality_proof(block_num, &validator_set, keys);
let good_proof = proof.clone().into(); let good_proof = proof.clone().into();
// should verify successfully // should verify successfully
@@ -132,7 +134,10 @@ pub(crate) mod tests {
// wrong signatures length -> should fail verification // wrong signatures length -> should fail verification
let mut bad_proof = proof.clone(); let mut bad_proof = proof.clone();
// change length of signatures // change length of signatures
bad_proof.signatures.pop().flatten().unwrap(); let bad_signed_commitment = match bad_proof {
VersionedFinalityProof::V1(ref mut sc) => sc,
};
bad_signed_commitment.signatures.pop().flatten().unwrap();
match verify_with_validator_set::<Block>(block_num + 1, &validator_set, &bad_proof.into()) { match verify_with_validator_set::<Block>(block_num + 1, &validator_set, &bad_proof.into()) {
Err(ConsensusError::InvalidJustification) => (), Err(ConsensusError::InvalidJustification) => (),
_ => assert!(false, "Expected Err(ConsensusError::InvalidJustification)"), _ => assert!(false, "Expected Err(ConsensusError::InvalidJustification)"),
@@ -140,8 +145,11 @@ pub(crate) mod tests {
// not enough signatures -> should fail verification // not enough signatures -> should fail verification
let mut bad_proof = proof.clone(); let mut bad_proof = proof.clone();
let bad_signed_commitment = match bad_proof {
VersionedFinalityProof::V1(ref mut sc) => sc,
};
// remove a signature (but same length) // remove a signature (but same length)
*bad_proof.signatures.first_mut().unwrap() = None; *bad_signed_commitment.signatures.first_mut().unwrap() = None;
match verify_with_validator_set::<Block>(block_num + 1, &validator_set, &bad_proof.into()) { match verify_with_validator_set::<Block>(block_num + 1, &validator_set, &bad_proof.into()) {
Err(ConsensusError::InvalidJustification) => (), Err(ConsensusError::InvalidJustification) => (),
_ => assert!(false, "Expected Err(ConsensusError::InvalidJustification)"), _ => assert!(false, "Expected Err(ConsensusError::InvalidJustification)"),
@@ -149,9 +157,12 @@ pub(crate) mod tests {
// not enough _correct_ signatures -> should fail verification // not enough _correct_ signatures -> should fail verification
let mut bad_proof = proof.clone(); let mut bad_proof = proof.clone();
let bad_signed_commitment = match bad_proof {
VersionedFinalityProof::V1(ref mut sc) => sc,
};
// change a signature to a different key // change a signature to a different key
*bad_proof.signatures.first_mut().unwrap() = *bad_signed_commitment.signatures.first_mut().unwrap() =
Some(Keyring::Dave.sign(&proof.commitment.encode())); Some(Keyring::Dave.sign(&bad_signed_commitment.commitment.encode()));
match verify_with_validator_set::<Block>(block_num + 1, &validator_set, &bad_proof.into()) { match verify_with_validator_set::<Block>(block_num + 1, &validator_set, &bad_proof.into()) {
Err(ConsensusError::InvalidJustification) => (), Err(ConsensusError::InvalidJustification) => (),
_ => assert!(false, "Expected Err(ConsensusError::InvalidJustification)"), _ => assert!(false, "Expected Err(ConsensusError::InvalidJustification)"),
@@ -159,19 +170,19 @@ pub(crate) mod tests {
} }
#[test] #[test]
fn should_decode_and_verify_commitment() { fn should_decode_and_verify_finality_proof() {
let keys = &[Keyring::Alice, Keyring::Bob]; let keys = &[Keyring::Alice, Keyring::Bob];
let validator_set = ValidatorSet::new(make_beefy_ids(keys), 0).unwrap(); let validator_set = ValidatorSet::new(make_beefy_ids(keys), 0).unwrap();
let block_num = 1; let block_num = 1;
// build valid justification // build valid justification
let proof = new_signed_commitment(block_num, &validator_set, keys); let proof = new_finality_proof(block_num, &validator_set, keys);
let versioned_proof: VersionedFinalityProof<NumberFor<Block>, Signature> = proof.into(); let versioned_proof: BeefyVersionedFinalityProof<Block> = proof.into();
let encoded = versioned_proof.encode(); let encoded = versioned_proof.encode();
// should successfully decode and verify // should successfully decode and verify
let verified = let verified =
decode_and_verify_commitment::<Block>(&encoded, block_num, &validator_set).unwrap(); decode_and_verify_finality_proof::<Block>(&encoded, block_num, &validator_set).unwrap();
assert_eq!(verified, versioned_proof); assert_eq!(verified, versioned_proof);
} }
} }
+7 -7
View File
@@ -46,8 +46,8 @@ mod tests;
use crate::{ use crate::{
import::BeefyBlockImport, import::BeefyBlockImport,
notification::{ notification::{
BeefyBestBlockSender, BeefyBestBlockStream, BeefySignedCommitmentSender, BeefyBestBlockSender, BeefyBestBlockStream, BeefyVersionedFinalityProofSender,
BeefySignedCommitmentStream, BeefyVersionedFinalityProofStream,
}, },
}; };
@@ -121,11 +121,11 @@ where
pub struct BeefyVoterLinks<B: Block> { pub struct BeefyVoterLinks<B: Block> {
// BlockImport -> Voter links // BlockImport -> Voter links
/// Stream of BEEFY signed commitments from block import to voter. /// Stream of BEEFY signed commitments from block import to voter.
pub from_block_import_justif_stream: BeefySignedCommitmentStream<B>, pub from_block_import_justif_stream: BeefyVersionedFinalityProofStream<B>,
// Voter -> RPC links // Voter -> RPC links
/// Sends BEEFY signed commitments from voter to RPC. /// Sends BEEFY signed commitments from voter to RPC.
pub to_rpc_justif_sender: BeefySignedCommitmentSender<B>, pub to_rpc_justif_sender: BeefyVersionedFinalityProofSender<B>,
/// Sends BEEFY best block hashes from voter to RPC. /// Sends BEEFY best block hashes from voter to RPC.
pub to_rpc_best_block_sender: BeefyBestBlockSender<B>, pub to_rpc_best_block_sender: BeefyBestBlockSender<B>,
} }
@@ -134,7 +134,7 @@ pub struct BeefyVoterLinks<B: Block> {
#[derive(Clone)] #[derive(Clone)]
pub struct BeefyRPCLinks<B: Block> { pub struct BeefyRPCLinks<B: Block> {
/// Stream of signed commitments coming from the voter. /// Stream of signed commitments coming from the voter.
pub from_voter_justif_stream: BeefySignedCommitmentStream<B>, pub from_voter_justif_stream: BeefyVersionedFinalityProofStream<B>,
/// Stream of BEEFY best block hashes coming from the voter. /// Stream of BEEFY best block hashes coming from the voter.
pub from_voter_best_beefy_stream: BeefyBestBlockStream<B>, pub from_voter_best_beefy_stream: BeefyBestBlockStream<B>,
} }
@@ -156,13 +156,13 @@ where
{ {
// Voter -> RPC links // Voter -> RPC links
let (to_rpc_justif_sender, from_voter_justif_stream) = let (to_rpc_justif_sender, from_voter_justif_stream) =
notification::BeefySignedCommitmentStream::<B>::channel(); notification::BeefyVersionedFinalityProofStream::<B>::channel();
let (to_rpc_best_block_sender, from_voter_best_beefy_stream) = let (to_rpc_best_block_sender, from_voter_best_beefy_stream) =
notification::BeefyBestBlockStream::<B>::channel(); notification::BeefyBestBlockStream::<B>::channel();
// BlockImport -> Voter links // BlockImport -> Voter links
let (to_voter_justif_sender, from_block_import_justif_stream) = let (to_voter_justif_sender, from_block_import_justif_stream) =
notification::BeefySignedCommitmentStream::<B>::channel(); notification::BeefyVersionedFinalityProofStream::<B>::channel();
// BlockImport // BlockImport
let import = let import =
+11 -10
View File
@@ -19,7 +19,7 @@
use sc_utils::notification::{NotificationSender, NotificationStream, TracingKeyStr}; use sc_utils::notification::{NotificationSender, NotificationStream, TracingKeyStr};
use sp_runtime::traits::Block as BlockT; use sp_runtime::traits::Block as BlockT;
use crate::justification::BeefySignedCommitment; use crate::justification::BeefyVersionedFinalityProof;
/// The sending half of the notifications channel(s) used to send /// The sending half of the notifications channel(s) used to send
/// notifications about best BEEFY block from the gadget side. /// notifications about best BEEFY block from the gadget side.
@@ -31,13 +31,14 @@ pub type BeefyBestBlockStream<Block> =
NotificationStream<<Block as BlockT>::Hash, BeefyBestBlockTracingKey>; NotificationStream<<Block as BlockT>::Hash, BeefyBestBlockTracingKey>;
/// The sending half of the notifications channel(s) used to send notifications /// The sending half of the notifications channel(s) used to send notifications
/// about signed commitments generated at the end of a BEEFY round. /// about versioned finality proof generated at the end of a BEEFY round.
pub type BeefySignedCommitmentSender<Block> = NotificationSender<BeefySignedCommitment<Block>>; pub type BeefyVersionedFinalityProofSender<Block> =
NotificationSender<BeefyVersionedFinalityProof<Block>>;
/// The receiving half of a notifications channel used to receive notifications /// The receiving half of a notifications channel used to receive notifications
/// about signed commitments generated at the end of a BEEFY round. /// about versioned finality proof generated at the end of a BEEFY round.
pub type BeefySignedCommitmentStream<Block> = pub type BeefyVersionedFinalityProofStream<Block> =
NotificationStream<BeefySignedCommitment<Block>, BeefySignedCommitmentTracingKey>; NotificationStream<BeefyVersionedFinalityProof<Block>, BeefyVersionedFinalityProofTracingKey>;
/// Provides tracing key for BEEFY best block stream. /// Provides tracing key for BEEFY best block stream.
#[derive(Clone)] #[derive(Clone)]
@@ -46,9 +47,9 @@ impl TracingKeyStr for BeefyBestBlockTracingKey {
const TRACING_KEY: &'static str = "mpsc_beefy_best_block_notification_stream"; const TRACING_KEY: &'static str = "mpsc_beefy_best_block_notification_stream";
} }
/// Provides tracing key for BEEFY signed commitments stream. /// Provides tracing key for BEEFY versioned finality proof stream.
#[derive(Clone)] #[derive(Clone)]
pub struct BeefySignedCommitmentTracingKey; pub struct BeefyVersionedFinalityProofTracingKey;
impl TracingKeyStr for BeefySignedCommitmentTracingKey { impl TracingKeyStr for BeefyVersionedFinalityProofTracingKey {
const TRACING_KEY: &'static str = "mpsc_beefy_signed_commitments_notification_stream"; const TRACING_KEY: &'static str = "mpsc_beefy_versioned_finality_proof_notification_stream";
} }
+27 -23
View File
@@ -397,17 +397,18 @@ fn run_for(duration: Duration, net: &Arc<Mutex<BeefyTestNet>>, runtime: &mut Run
pub(crate) fn get_beefy_streams( pub(crate) fn get_beefy_streams(
net: &mut BeefyTestNet, net: &mut BeefyTestNet,
peers: &[BeefyKeyring], peers: &[BeefyKeyring],
) -> (Vec<NotificationReceiver<H256>>, Vec<NotificationReceiver<BeefySignedCommitment<Block>>>) { ) -> (Vec<NotificationReceiver<H256>>, Vec<NotificationReceiver<BeefyVersionedFinalityProof<Block>>>)
{
let mut best_block_streams = Vec::new(); let mut best_block_streams = Vec::new();
let mut signed_commitment_streams = Vec::new(); let mut versioned_finality_proof_streams = Vec::new();
for peer_id in 0..peers.len() { for peer_id in 0..peers.len() {
let beefy_rpc_links = net.peer(peer_id).data.beefy_rpc_links.lock().clone().unwrap(); let beefy_rpc_links = net.peer(peer_id).data.beefy_rpc_links.lock().clone().unwrap();
let BeefyRPCLinks { from_voter_justif_stream, from_voter_best_beefy_stream } = let BeefyRPCLinks { from_voter_justif_stream, from_voter_best_beefy_stream } =
beefy_rpc_links; beefy_rpc_links;
best_block_streams.push(from_voter_best_beefy_stream.subscribe()); best_block_streams.push(from_voter_best_beefy_stream.subscribe());
signed_commitment_streams.push(from_voter_justif_stream.subscribe()); versioned_finality_proof_streams.push(from_voter_justif_stream.subscribe());
} }
(best_block_streams, signed_commitment_streams) (best_block_streams, versioned_finality_proof_streams)
} }
fn wait_for_best_beefy_blocks( fn wait_for_best_beefy_blocks(
@@ -437,7 +438,7 @@ fn wait_for_best_beefy_blocks(
} }
fn wait_for_beefy_signed_commitments( fn wait_for_beefy_signed_commitments(
streams: Vec<NotificationReceiver<BeefySignedCommitment<Block>>>, streams: Vec<NotificationReceiver<BeefyVersionedFinalityProof<Block>>>,
net: &Arc<Mutex<BeefyTestNet>>, net: &Arc<Mutex<BeefyTestNet>>,
runtime: &mut Runtime, runtime: &mut Runtime,
expected_commitment_block_nums: &[u64], expected_commitment_block_nums: &[u64],
@@ -446,9 +447,12 @@ fn wait_for_beefy_signed_commitments(
let len = expected_commitment_block_nums.len(); let len = expected_commitment_block_nums.len();
streams.into_iter().for_each(|stream| { streams.into_iter().for_each(|stream| {
let mut expected = expected_commitment_block_nums.iter(); let mut expected = expected_commitment_block_nums.iter();
wait_for.push(Box::pin(stream.take(len).for_each(move |signed_commitment| { wait_for.push(Box::pin(stream.take(len).for_each(move |versioned_finality_proof| {
let expected = expected.next(); let expected = expected.next();
async move { async move {
let signed_commitment = match versioned_finality_proof {
beefy_primitives::VersionedFinalityProof::V1(sc) => sc,
};
let commitment_block_num = signed_commitment.commitment.block_number; let commitment_block_num = signed_commitment.commitment.block_number;
assert_eq!(expected, Some(commitment_block_num).as_ref()); assert_eq!(expected, Some(commitment_block_num).as_ref());
// TODO: also verify commitment payload, validator set id, and signatures. // TODO: also verify commitment payload, validator set id, and signatures.
@@ -486,7 +490,7 @@ fn finalize_block_and_wait_for_beefy(
finalize_targets: &[u64], finalize_targets: &[u64],
expected_beefy: &[u64], expected_beefy: &[u64],
) { ) {
let (best_blocks, signed_commitments) = get_beefy_streams(&mut net.lock(), peers); let (best_blocks, versioned_finality_proof) = get_beefy_streams(&mut net.lock(), peers);
for block in finalize_targets { for block in finalize_targets {
let finalize = BlockId::number(*block); let finalize = BlockId::number(*block);
@@ -499,11 +503,11 @@ fn finalize_block_and_wait_for_beefy(
// run for quarter second then verify no new best beefy block available // run for quarter second then verify no new best beefy block available
let timeout = Some(Duration::from_millis(250)); let timeout = Some(Duration::from_millis(250));
streams_empty_after_timeout(best_blocks, &net, runtime, timeout); streams_empty_after_timeout(best_blocks, &net, runtime, timeout);
streams_empty_after_timeout(signed_commitments, &net, runtime, None); streams_empty_after_timeout(versioned_finality_proof, &net, runtime, None);
} else { } else {
// run until expected beefy blocks are received // run until expected beefy blocks are received
wait_for_best_beefy_blocks(best_blocks, &net, runtime, expected_beefy); wait_for_best_beefy_blocks(best_blocks, &net, runtime, expected_beefy);
wait_for_beefy_signed_commitments(signed_commitments, &net, runtime, expected_beefy); wait_for_beefy_signed_commitments(versioned_finality_proof, &net, runtime, expected_beefy);
} }
} }
@@ -574,19 +578,19 @@ fn lagging_validators() {
// Alice finalizes #25, Bob lags behind // Alice finalizes #25, Bob lags behind
let finalize = BlockId::number(25); let finalize = BlockId::number(25);
let (best_blocks, signed_commitments) = get_beefy_streams(&mut net.lock(), peers); let (best_blocks, versioned_finality_proof) = get_beefy_streams(&mut net.lock(), peers);
net.lock().peer(0).client().as_client().finalize_block(finalize, None).unwrap(); net.lock().peer(0).client().as_client().finalize_block(finalize, None).unwrap();
// verify nothing gets finalized by BEEFY // verify nothing gets finalized by BEEFY
let timeout = Some(Duration::from_millis(250)); let timeout = Some(Duration::from_millis(250));
streams_empty_after_timeout(best_blocks, &net, &mut runtime, timeout); streams_empty_after_timeout(best_blocks, &net, &mut runtime, timeout);
streams_empty_after_timeout(signed_commitments, &net, &mut runtime, None); streams_empty_after_timeout(versioned_finality_proof, &net, &mut runtime, None);
// Bob catches up and also finalizes #25 // Bob catches up and also finalizes #25
let (best_blocks, signed_commitments) = get_beefy_streams(&mut net.lock(), peers); let (best_blocks, versioned_finality_proof) = get_beefy_streams(&mut net.lock(), peers);
net.lock().peer(1).client().as_client().finalize_block(finalize, None).unwrap(); net.lock().peer(1).client().as_client().finalize_block(finalize, None).unwrap();
// expected beefy finalizes block #17 from diff-power-of-two // expected beefy finalizes block #17 from diff-power-of-two
wait_for_best_beefy_blocks(best_blocks, &net, &mut runtime, &[23, 24, 25]); wait_for_best_beefy_blocks(best_blocks, &net, &mut runtime, &[23, 24, 25]);
wait_for_beefy_signed_commitments(signed_commitments, &net, &mut runtime, &[23, 24, 25]); wait_for_beefy_signed_commitments(versioned_finality_proof, &net, &mut runtime, &[23, 24, 25]);
// Both finalize #30 (mandatory session) and #32 -> BEEFY finalize #30 (mandatory), #31, #32 // Both finalize #30 (mandatory session) and #32 -> BEEFY finalize #30 (mandatory), #31, #32
finalize_block_and_wait_for_beefy(&net, peers, &mut runtime, &[30, 32], &[30, 31, 32]); finalize_block_and_wait_for_beefy(&net, peers, &mut runtime, &[30, 32], &[30, 31, 32]);
@@ -596,20 +600,20 @@ fn lagging_validators() {
// validator set). // validator set).
// Alice finalizes session-boundary mandatory block #60, Bob lags behind // Alice finalizes session-boundary mandatory block #60, Bob lags behind
let (best_blocks, signed_commitments) = get_beefy_streams(&mut net.lock(), peers); let (best_blocks, versioned_finality_proof) = get_beefy_streams(&mut net.lock(), peers);
let finalize = BlockId::number(60); let finalize = BlockId::number(60);
net.lock().peer(0).client().as_client().finalize_block(finalize, None).unwrap(); net.lock().peer(0).client().as_client().finalize_block(finalize, None).unwrap();
// verify nothing gets finalized by BEEFY // verify nothing gets finalized by BEEFY
let timeout = Some(Duration::from_millis(250)); let timeout = Some(Duration::from_millis(250));
streams_empty_after_timeout(best_blocks, &net, &mut runtime, timeout); streams_empty_after_timeout(best_blocks, &net, &mut runtime, timeout);
streams_empty_after_timeout(signed_commitments, &net, &mut runtime, None); streams_empty_after_timeout(versioned_finality_proof, &net, &mut runtime, None);
// Bob catches up and also finalizes #60 (and should have buffered Alice's vote on #60) // Bob catches up and also finalizes #60 (and should have buffered Alice's vote on #60)
let (best_blocks, signed_commitments) = get_beefy_streams(&mut net.lock(), peers); let (best_blocks, versioned_finality_proof) = get_beefy_streams(&mut net.lock(), peers);
net.lock().peer(1).client().as_client().finalize_block(finalize, None).unwrap(); net.lock().peer(1).client().as_client().finalize_block(finalize, None).unwrap();
// verify beefy skips intermediary votes, and successfully finalizes mandatory block #40 // verify beefy skips intermediary votes, and successfully finalizes mandatory block #40
wait_for_best_beefy_blocks(best_blocks, &net, &mut runtime, &[60]); wait_for_best_beefy_blocks(best_blocks, &net, &mut runtime, &[60]);
wait_for_beefy_signed_commitments(signed_commitments, &net, &mut runtime, &[60]); wait_for_beefy_signed_commitments(versioned_finality_proof, &net, &mut runtime, &[60]);
} }
#[test] #[test]
@@ -647,7 +651,7 @@ fn correct_beefy_payload() {
// with 3 good voters and 1 bad one, consensus should happen and best blocks produced. // with 3 good voters and 1 bad one, consensus should happen and best blocks produced.
finalize_block_and_wait_for_beefy(&net, peers, &mut runtime, &[10], &[1, 9]); finalize_block_and_wait_for_beefy(&net, peers, &mut runtime, &[10], &[1, 9]);
let (best_blocks, signed_commitments) = let (best_blocks, versioned_finality_proof) =
get_beefy_streams(&mut net.lock(), &[BeefyKeyring::Alice]); get_beefy_streams(&mut net.lock(), &[BeefyKeyring::Alice]);
// now 2 good validators and 1 bad one are voting // now 2 good validators and 1 bad one are voting
@@ -673,10 +677,10 @@ fn correct_beefy_payload() {
// verify consensus is _not_ reached // verify consensus is _not_ reached
let timeout = Some(Duration::from_millis(250)); let timeout = Some(Duration::from_millis(250));
streams_empty_after_timeout(best_blocks, &net, &mut runtime, timeout); streams_empty_after_timeout(best_blocks, &net, &mut runtime, timeout);
streams_empty_after_timeout(signed_commitments, &net, &mut runtime, None); streams_empty_after_timeout(versioned_finality_proof, &net, &mut runtime, None);
// 3rd good validator catches up and votes as well // 3rd good validator catches up and votes as well
let (best_blocks, signed_commitments) = let (best_blocks, versioned_finality_proof) =
get_beefy_streams(&mut net.lock(), &[BeefyKeyring::Alice]); get_beefy_streams(&mut net.lock(), &[BeefyKeyring::Alice]);
net.lock() net.lock()
.peer(2) .peer(2)
@@ -687,7 +691,7 @@ fn correct_beefy_payload() {
// verify consensus is reached // verify consensus is reached
wait_for_best_beefy_blocks(best_blocks, &net, &mut runtime, &[11]); wait_for_best_beefy_blocks(best_blocks, &net, &mut runtime, &[11]);
wait_for_beefy_signed_commitments(signed_commitments, &net, &mut runtime, &[11]); wait_for_beefy_signed_commitments(versioned_finality_proof, &net, &mut runtime, &[11]);
} }
#[test] #[test]
@@ -746,7 +750,7 @@ fn beefy_importing_blocks() {
let block_num = 2; let block_num = 2;
let keys = &[BeefyKeyring::Alice, BeefyKeyring::Bob]; let keys = &[BeefyKeyring::Alice, BeefyKeyring::Bob];
let validator_set = ValidatorSet::new(make_beefy_ids(keys), 0).unwrap(); let validator_set = ValidatorSet::new(make_beefy_ids(keys), 0).unwrap();
let proof = crate::justification::tests::new_signed_commitment(block_num, &validator_set, keys); let proof = crate::justification::tests::new_finality_proof(block_num, &validator_set, keys);
let versioned_proof: VersionedFinalityProof<NumberFor<Block>, Signature> = proof.into(); let versioned_proof: VersionedFinalityProof<NumberFor<Block>, Signature> = proof.into();
let encoded = versioned_proof.encode(); let encoded = versioned_proof.encode();
let justif = Some(Justifications::from((BEEFY_ENGINE_ID, encoded))); let justif = Some(Justifications::from((BEEFY_ENGINE_ID, encoded)));
@@ -781,7 +785,7 @@ fn beefy_importing_blocks() {
let block_num = 3; let block_num = 3;
let keys = &[BeefyKeyring::Alice]; let keys = &[BeefyKeyring::Alice];
let validator_set = ValidatorSet::new(make_beefy_ids(keys), 1).unwrap(); let validator_set = ValidatorSet::new(make_beefy_ids(keys), 1).unwrap();
let proof = crate::justification::tests::new_signed_commitment(block_num, &validator_set, keys); let proof = crate::justification::tests::new_finality_proof(block_num, &validator_set, keys);
let versioned_proof: VersionedFinalityProof<NumberFor<Block>, Signature> = proof.into(); let versioned_proof: VersionedFinalityProof<NumberFor<Block>, Signature> = proof.into();
let encoded = versioned_proof.encode(); let encoded = versioned_proof.encode();
let justif = Some(Justifications::from((BEEFY_ENGINE_ID, encoded))); let justif = Some(Justifications::from((BEEFY_ENGINE_ID, encoded)));
+37 -33
View File
@@ -49,7 +49,7 @@ use beefy_primitives::{
use crate::{ use crate::{
error::Error, error::Error,
gossip::{topic, GossipValidator}, gossip::{topic, GossipValidator},
justification::BeefySignedCommitment, justification::BeefyVersionedFinalityProof,
keystore::BeefyKeystore, keystore::BeefyKeystore,
metric_inc, metric_set, metric_inc, metric_set,
metrics::Metrics, metrics::Metrics,
@@ -212,7 +212,7 @@ pub(crate) struct BeefyWorker<B: Block, BE, C, R, SO> {
/// Buffer holding votes for future processing. /// Buffer holding votes for future processing.
pending_votes: BTreeMap<NumberFor<B>, Vec<VoteMessage<NumberFor<B>, AuthorityId, Signature>>>, pending_votes: BTreeMap<NumberFor<B>, Vec<VoteMessage<NumberFor<B>, AuthorityId, Signature>>>,
/// Buffer holding justifications for future processing. /// Buffer holding justifications for future processing.
pending_justifications: BTreeMap<NumberFor<B>, Vec<BeefySignedCommitment<B>>>, pending_justifications: BTreeMap<NumberFor<B>, Vec<BeefyVersionedFinalityProof<B>>>,
/// Chooses which incoming votes to accept and which votes to generate. /// Chooses which incoming votes to accept and which votes to generate.
voting_oracle: VoterOracle<B>, voting_oracle: VoterOracle<B>,
} }
@@ -381,9 +381,12 @@ where
/// Expects `justification` to be valid. /// Expects `justification` to be valid.
fn triage_incoming_justif( fn triage_incoming_justif(
&mut self, &mut self,
justification: BeefySignedCommitment<B>, justification: BeefyVersionedFinalityProof<B>,
) -> Result<(), Error> { ) -> Result<(), Error> {
let block_num = justification.commitment.block_number; let signed_commitment = match justification {
VersionedFinalityProof::V1(ref sc) => sc,
};
let block_num = signed_commitment.commitment.block_number;
let best_grandpa = *self.best_grandpa_block_header.number(); let best_grandpa = *self.best_grandpa_block_header.number();
match self.voting_oracle.triage_round(block_num, best_grandpa)? { match self.voting_oracle.triage_round(block_num, best_grandpa)? {
RoundAction::Process => self.finalize(justification), RoundAction::Process => self.finalize(justification),
@@ -417,39 +420,39 @@ where
validator_set_id: rounds.validator_set_id(), validator_set_id: rounds.validator_set_id(),
}; };
let signed_commitment = SignedCommitment { commitment, signatures }; let finality_proof =
VersionedFinalityProof::V1(SignedCommitment { commitment, signatures });
metric_set!(self, beefy_round_concluded, block_num); metric_set!(self, beefy_round_concluded, block_num);
info!(target: "beefy", "🥩 Round #{} concluded, committed: {:?}.", round.1, signed_commitment); info!(target: "beefy", "🥩 Round #{} concluded, finality_proof: {:?}.", round.1, finality_proof);
if let Err(e) = self.backend.append_justification( if let Err(e) = self.backend.append_justification(
BlockId::Number(block_num), BlockId::Number(block_num),
( (BEEFY_ENGINE_ID, finality_proof.clone().encode()),
BEEFY_ENGINE_ID,
VersionedFinalityProof::V1(signed_commitment.clone()).encode(),
),
) { ) {
debug!(target: "beefy", "🥩 Error {:?} on appending justification: {:?}", e, signed_commitment); debug!(target: "beefy", "🥩 Error {:?} on appending justification: {:?}", e, finality_proof);
} }
// We created the `signed_commitment` and know to be valid. // We created the `finality_proof` and know to be valid.
self.finalize(signed_commitment); self.finalize(finality_proof);
} }
} }
Ok(()) Ok(())
} }
/// Provide BEEFY finality for block based on `signed_commitment`: /// Provide BEEFY finality for block based on `finality_proof`:
/// 1. Prune irrelevant past sessions from the oracle, /// 1. Prune irrelevant past sessions from the oracle,
/// 2. Set BEEFY best block, /// 2. Set BEEFY best block,
/// 3. Send best block hash and `signed_commitment` to RPC worker. /// 3. Send best block hash and `finality_proof` to RPC worker.
/// ///
/// Expects `signed commitment` to be valid. /// Expects `finality proof` to be valid.
fn finalize(&mut self, signed_commitment: BeefySignedCommitment<B>) { fn finalize(&mut self, finality_proof: BeefyVersionedFinalityProof<B>) {
// Prune any now "finalized" sessions from queue. // Prune any now "finalized" sessions from queue.
self.voting_oracle.try_prune(); self.voting_oracle.try_prune();
let signed_commitment = match finality_proof {
VersionedFinalityProof::V1(ref sc) => sc,
};
let block_num = signed_commitment.commitment.block_number; let block_num = signed_commitment.commitment.block_number;
if Some(block_num) > self.best_beefy_block { if Some(block_num) > self.best_beefy_block {
// Set new best BEEFY block number. // Set new best BEEFY block number.
@@ -465,7 +468,7 @@ where
self.links self.links
.to_rpc_justif_sender .to_rpc_justif_sender
.notify(|| Ok::<_, ()>(signed_commitment)) .notify(|| Ok::<_, ()>(finality_proof))
.expect("forwards closure result; the closure always returns Ok; qed."); .expect("forwards closure result; the closure always returns Ok; qed.");
} else { } else {
debug!(target: "beefy", "🥩 Can't set best beefy to older: {}", block_num); debug!(target: "beefy", "🥩 Can't set best beefy to older: {}", block_num);
@@ -832,7 +835,7 @@ pub(crate) mod tests {
use super::*; use super::*;
use crate::{ use crate::{
keystore::tests::Keyring, keystore::tests::Keyring,
notification::{BeefyBestBlockStream, BeefySignedCommitmentStream}, notification::{BeefyBestBlockStream, BeefyVersionedFinalityProofStream},
tests::{ tests::{
create_beefy_keystore, get_beefy_streams, make_beefy_ids, two_validators::TestApi, create_beefy_keystore, get_beefy_streams, make_beefy_ids, two_validators::TestApi,
BeefyPeer, BeefyTestNet, BEEFY_PROTOCOL_NAME, BeefyPeer, BeefyTestNet, BEEFY_PROTOCOL_NAME,
@@ -859,10 +862,11 @@ pub(crate) mod tests {
let keystore = create_beefy_keystore(*key); let keystore = create_beefy_keystore(*key);
let (to_rpc_justif_sender, from_voter_justif_stream) = let (to_rpc_justif_sender, from_voter_justif_stream) =
BeefySignedCommitmentStream::<Block>::channel(); BeefyVersionedFinalityProofStream::<Block>::channel();
let (to_rpc_best_block_sender, from_voter_best_beefy_stream) = let (to_rpc_best_block_sender, from_voter_best_beefy_stream) =
BeefyBestBlockStream::<Block>::channel(); BeefyBestBlockStream::<Block>::channel();
let (_, from_block_import_justif_stream) = BeefySignedCommitmentStream::<Block>::channel(); let (_, from_block_import_justif_stream) =
BeefyVersionedFinalityProofStream::<Block>::channel();
let beefy_rpc_links = let beefy_rpc_links =
BeefyRPCLinks { from_voter_justif_stream, from_voter_best_beefy_stream }; BeefyRPCLinks { from_voter_justif_stream, from_voter_best_beefy_stream };
@@ -1168,37 +1172,37 @@ pub(crate) mod tests {
let mut net = BeefyTestNet::new(1, 0); let mut net = BeefyTestNet::new(1, 0);
let mut worker = create_beefy_worker(&net.peer(0), &keys[0], 1); let mut worker = create_beefy_worker(&net.peer(0), &keys[0], 1);
let (mut best_block_streams, mut signed_commitments) = get_beefy_streams(&mut net, keys); let (mut best_block_streams, mut finality_proofs) = get_beefy_streams(&mut net, keys);
let mut best_block_stream = best_block_streams.drain(..).next().unwrap(); let mut best_block_stream = best_block_streams.drain(..).next().unwrap();
let mut signed_commitments = signed_commitments.drain(..).next().unwrap(); let mut finality_proof = finality_proofs.drain(..).next().unwrap();
let create_signed_commitment = |block_num: NumberFor<Block>| { let create_finality_proof = |block_num: NumberFor<Block>| {
let commitment = Commitment { let commitment = Commitment {
payload: Payload::new(known_payload_ids::MMR_ROOT_ID, vec![]), payload: Payload::new(known_payload_ids::MMR_ROOT_ID, vec![]),
block_number: block_num, block_number: block_num,
validator_set_id: validator_set.id(), validator_set_id: validator_set.id(),
}; };
SignedCommitment { commitment, signatures: vec![None] } VersionedFinalityProof::V1(SignedCommitment { commitment, signatures: vec![None] })
}; };
// no 'best beefy block' or signed commitments // no 'best beefy block' or finality proofs
assert_eq!(worker.best_beefy_block, None); assert_eq!(worker.best_beefy_block, None);
block_on(poll_fn(move |cx| { block_on(poll_fn(move |cx| {
assert_eq!(best_block_stream.poll_next_unpin(cx), Poll::Pending); assert_eq!(best_block_stream.poll_next_unpin(cx), Poll::Pending);
assert_eq!(signed_commitments.poll_next_unpin(cx), Poll::Pending); assert_eq!(finality_proof.poll_next_unpin(cx), Poll::Pending);
Poll::Ready(()) Poll::Ready(())
})); }));
// unknown hash for block #1 // unknown hash for block #1
let (mut best_block_streams, mut signed_commitments) = get_beefy_streams(&mut net, keys); let (mut best_block_streams, mut finality_proofs) = get_beefy_streams(&mut net, keys);
let mut best_block_stream = best_block_streams.drain(..).next().unwrap(); let mut best_block_stream = best_block_streams.drain(..).next().unwrap();
let mut signed_commitments = signed_commitments.drain(..).next().unwrap(); let mut finality_proof = finality_proofs.drain(..).next().unwrap();
let justif = create_signed_commitment(1); let justif = create_finality_proof(1);
worker.finalize(justif.clone()); worker.finalize(justif.clone());
assert_eq!(worker.best_beefy_block, Some(1)); assert_eq!(worker.best_beefy_block, Some(1));
block_on(poll_fn(move |cx| { block_on(poll_fn(move |cx| {
assert_eq!(best_block_stream.poll_next_unpin(cx), Poll::Pending); assert_eq!(best_block_stream.poll_next_unpin(cx), Poll::Pending);
match signed_commitments.poll_next_unpin(cx) { match finality_proof.poll_next_unpin(cx) {
// expect justification // expect justification
Poll::Ready(Some(received)) => assert_eq!(received, justif), Poll::Ready(Some(received)) => assert_eq!(received, justif),
v => panic!("unexpected value: {:?}", v), v => panic!("unexpected value: {:?}", v),
@@ -1211,7 +1215,7 @@ pub(crate) mod tests {
let mut best_block_stream = best_block_streams.drain(..).next().unwrap(); let mut best_block_stream = best_block_streams.drain(..).next().unwrap();
net.generate_blocks(2, 10, &validator_set, false); net.generate_blocks(2, 10, &validator_set, false);
let justif = create_signed_commitment(2); let justif = create_finality_proof(2);
worker.finalize(justif); worker.finalize(justif);
assert_eq!(worker.best_beefy_block, Some(2)); assert_eq!(worker.best_beefy_block, Some(2));
block_on(poll_fn(move |cx| { block_on(poll_fn(move |cx| {