Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Append SignedCommitment to block justifications (#177)
Browse files Browse the repository at this point in the history
* Append SignedCommitment

* add BeefyParams

* add WorkerParams

* use warn

* versioned variant for SignedCommitment
  • Loading branch information
adoerr authored May 11, 2021
1 parent 532c858 commit 088fa19
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 26 deletions.
55 changes: 41 additions & 14 deletions client/beefy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ use sc_network_gossip::{GossipEngine, Network as GossipNetwork};
use sp_api::ProvideRuntimeApi;
use sp_application_crypto::AppPublic;
use sp_blockchain::HeaderBackend;
use sp_consensus::SyncOracle as SyncOracleT;
use sp_keystore::SyncCryptoStorePtr;
use sp_runtime::traits::Block;

Expand Down Expand Up @@ -78,18 +77,34 @@ where
// empty
}

/// BEEFY gadget initialization parameters.
pub struct BeefyParams<B, P, BE, C, N>
where
B: Block,
P: sp_core::Pair,
P::Signature: Clone + Codec + Debug + PartialEq + TryFrom<Vec<u8>>,
{
/// BEEFY client
pub client: Arc<C>,
/// Client Backend
pub backend: Arc<BE>,
/// Local key store
pub key_store: Option<SyncCryptoStorePtr>,
/// Gossip network
pub network: N,
/// BEEFY signed commitment sender
pub signed_commitment_sender: notification::BeefySignedCommitmentSender<B, P::Signature>,
/// Minimal delta between blocks, BEEFY should vote for
pub min_block_delta: u32,
/// Prometheus metric registry
pub prometheus_registry: Option<Registry>,
}

/// Start the BEEFY gadget.
///
/// This is a thin shim around running and awaiting a BEEFY worker.
pub async fn start_beefy_gadget<B, P, BE, C, N, SO>(
client: Arc<C>,
key_store: Option<SyncCryptoStorePtr>,
network: N,
signed_commitment_sender: notification::BeefySignedCommitmentSender<B, P::Signature>,
_sync_oracle: SO,
min_block_delta: u32,
prometheus_registry: Option<Registry>,
) where
pub async fn start_beefy_gadget<B, P, BE, C, N>(beefy_params: BeefyParams<B, P, BE, C, N>)
where
B: Block,
P: sp_core::Pair,
P::Public: AppPublic + Codec,
Expand All @@ -98,8 +113,17 @@ pub async fn start_beefy_gadget<B, P, BE, C, N, SO>(
C: Client<B, BE, P>,
C::Api: BeefyApi<B, P::Public>,
N: GossipNetwork<B> + Clone + Send + 'static,
SO: SyncOracleT + Send + 'static,
{
let BeefyParams {
client,
backend,
key_store,
network,
signed_commitment_sender,
min_block_delta,
prometheus_registry,
} = beefy_params;

let gossip_validator = Arc::new(gossip::BeefyGossipValidator::new());
let gossip_engine = GossipEngine::new(network, BEEFY_PROTOCOL_NAME, gossip_validator.clone(), None);

Expand All @@ -117,15 +141,18 @@ pub async fn start_beefy_gadget<B, P, BE, C, N, SO>(
}
});

let worker = worker::BeefyWorker::<_, _, BE, P>::new(
client.clone(),
let worker_params = worker::WorkerParams {
client,
backend,
key_store,
signed_commitment_sender,
gossip_engine,
gossip_validator,
min_block_delta,
metrics,
);
};

let worker = worker::BeefyWorker::<_, _, _, _>::new(worker_params);

worker.run().await
}
59 changes: 48 additions & 11 deletions client/beefy/src/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ use sp_runtime::{
};

use beefy_primitives::{
BeefyApi, Commitment, ConsensusLog, MmrRootHash, SignedCommitment, ValidatorSet, VoteMessage, BEEFY_ENGINE_ID,
GENESIS_AUTHORITY_SET_ID, KEY_TYPE,
BeefyApi, Commitment, ConsensusLog, MmrRootHash, SignedCommitment, ValidatorSet, VersionedCommitment, VoteMessage,
BEEFY_ENGINE_ID, GENESIS_AUTHORITY_SET_ID, KEY_TYPE,
};

use crate::{
Expand All @@ -54,6 +54,22 @@ use crate::{
notification, round, Client,
};

pub(crate) struct WorkerParams<B, P, BE, C>
where
B: Block,
P: sp_core::Pair,
P::Signature: Clone + Codec + Debug + PartialEq + TryFrom<Vec<u8>>,
{
pub client: Arc<C>,
pub backend: Arc<BE>,
pub key_store: Option<SyncCryptoStorePtr>,
pub signed_commitment_sender: notification::BeefySignedCommitmentSender<B, P::Signature>,
pub gossip_engine: GossipEngine<B>,
pub gossip_validator: Arc<BeefyGossipValidator<B, P>>,
pub min_block_delta: u32,
pub metrics: Option<Metrics>,
}

/// A BEEFY worker plays the BEEFY protocol
pub(crate) struct BeefyWorker<B, C, BE, P>
where
Expand All @@ -65,6 +81,7 @@ where
C: Client<B, BE, P>,
{
client: Arc<C>,
backend: Arc<BE>,
key_store: Option<SyncCryptoStorePtr>,
signed_commitment_sender: notification::BeefySignedCommitmentSender<B, P::Signature>,
gossip_engine: Arc<Mutex<GossipEngine<B>>>,
Expand Down Expand Up @@ -101,17 +118,21 @@ where
/// BEEFY pallet has been deployed on-chain.
///
/// The BEEFY pallet is needed in order to keep track of the BEEFY authority set.
pub(crate) fn new(
client: Arc<C>,
key_store: Option<SyncCryptoStorePtr>,
signed_commitment_sender: notification::BeefySignedCommitmentSender<B, P::Signature>,
gossip_engine: GossipEngine<B>,
gossip_validator: Arc<BeefyGossipValidator<B, P>>,
min_block_delta: u32,
metrics: Option<Metrics>,
) -> Self {
pub(crate) fn new(worker_params: WorkerParams<B, P, BE, C>) -> Self {
let WorkerParams {
client,
backend,
key_store,
signed_commitment_sender,
gossip_engine,
gossip_validator,
min_block_delta,
metrics,
} = worker_params;

BeefyWorker {
client: client.clone(),
backend,
key_store,
signed_commitment_sender,
gossip_engine: Arc::new(Mutex::new(gossip_engine)),
Expand Down Expand Up @@ -313,6 +334,22 @@ where

debug!(target: "beefy", "🥩 Round #{} concluded, committed: {:?}.", round.1, signed_commitment);

if self
.backend
.append_justification(
BlockId::Number(round.1),
(
BEEFY_ENGINE_ID,
VersionedCommitment::V1(signed_commitment.clone()).encode(),
),
)
.is_err()
{
// this is a warning for now, because until the round lifecycle is improved, we will
// conclude certain rounds multiple times.
warn!(target: "beefy", "🥩 Failed to append justification: {:?}", signed_commitment);
}

self.signed_commitment_sender.notify(signed_commitment);
self.best_beefy_block = Some(round.1);

Expand Down
36 changes: 36 additions & 0 deletions primitives/beefy/src/commitment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,24 @@ impl<TBlockNumber, TPayload, TSignature> SignedCommitment<TBlockNumber, TPayload
}
}

/// A [SignedCommitment] with a version number. This variant will be appended
/// to the block justifications for the block for which the signed commitment
/// has been generated.
#[derive(Clone, Debug, PartialEq, codec::Encode, codec::Decode)]
pub enum VersionedCommitment<N, P, S> {
#[codec(index = 1)]
/// Current active version
V1(SignedCommitment<N, P, S>),
}

#[cfg(test)]
mod tests {
use super::*;
use codec::Decode;

type TestCommitment = Commitment<u128, String>;
type TestSignedCommitment = SignedCommitment<u128, String, Vec<u8>>;
type TestVersionedCommitment = VersionedCommitment<u128, String, Vec<u8>>;

#[test]
fn commitment_encode_decode() {
Expand Down Expand Up @@ -195,4 +206,29 @@ mod tests {
assert!(c < d);
assert!(b < d);
}

#[test]
fn versioned_commitment_encode_decode() {
let commitment: TestCommitment = Commitment {
payload: "Hello World!".into(),
block_number: 5,
validator_set_id: 0,
};

let signed = SignedCommitment {
commitment,
signatures: vec![None, None, Some(vec![1, 2, 3, 4]), Some(vec![5, 6, 7, 8])],
};

let versioned = TestVersionedCommitment::V1(signed.clone());

let encoded = codec::Encode::encode(&versioned);

assert_eq!(1, encoded[0]);
assert_eq!(encoded[1..], codec::Encode::encode(&signed));

let decoded = TestVersionedCommitment::decode(&mut &*encoded);

assert_eq!(decoded, Ok(versioned));
}
}
2 changes: 1 addition & 1 deletion primitives/beefy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
mod commitment;
pub mod witness;

pub use commitment::{Commitment, SignedCommitment};
pub use commitment::{Commitment, SignedCommitment, VersionedCommitment};

use codec::{Codec, Decode, Encode};
use sp_core::H256;
Expand Down

0 comments on commit 088fa19

Please sign in to comment.