Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,535 changes: 904 additions & 631 deletions Cargo.lock

Large diffs are not rendered by default.

146 changes: 76 additions & 70 deletions Cargo.toml

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions demo/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ sp-consensus-aura = { workspace = true }
sp-partner-chains-consensus-aura = { workspace = true }
sp-consensus = { workspace = true }
sc-consensus = { workspace = true }
sc-consensus-beefy = { workspace = true }
sc-consensus-beefy-rpc = { workspace = true }
sp-consensus-beefy = { workspace = true }
sc-consensus-grandpa = { workspace = true }
sc-consensus-grandpa-rpc = { workspace = true }
sp-consensus-grandpa = { workspace = true }
Expand Down
1 change: 1 addition & 0 deletions demo/node/src/chain_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ pub fn pc_create_chain_spec(config: &CreateChainSpecConfig<SessionKeys>) -> serd
system: partner_chains_demo_runtime::SystemConfig::default(),
balances: partner_chains_demo_runtime::BalancesConfig::default(),
aura: partner_chains_demo_runtime::AuraConfig::default(),
beefy: partner_chains_demo_runtime::BeefyConfig::default(),
grandpa: partner_chains_demo_runtime::GrandpaConfig::default(),
sudo: partner_chains_demo_runtime::SudoConfig::default(),
transaction_payment: Default::default(),
Expand Down
35 changes: 31 additions & 4 deletions demo/node/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ use partner_chains_demo_runtime::{
opaque::{Block, SessionKeys},
};
use partner_chains_demo_runtime::{BlockNumber, BlockProducerMetadataType, CrossChainPublic, Hash};
use sc_consensus_beefy::communication::notification::{
BeefyBestBlockStream, BeefyVersionedFinalityProofStream,
};
use sc_consensus_beefy_rpc::Beefy;
use sc_consensus_grandpa::{
FinalityProofProvider, GrandpaJustificationStream, SharedAuthoritySet, SharedVoterState,
};
Expand All @@ -30,6 +34,7 @@ use sidechain_domain::mainchain_epoch::MainchainEpochConfig;
use sp_api::ProvideRuntimeApi;
use sp_block_builder::BlockBuilder;
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
use sp_consensus_beefy::AuthorityIdBound;
use sp_session_validator_management_query::SessionValidatorManagementQuery;
use std::sync::Arc;
use time_source::TimeSource;
Expand All @@ -48,23 +53,35 @@ pub struct GrandpaDeps<B> {
pub finality_provider: Arc<FinalityProofProvider<B, Block>>,
}

/// Dependencies for BEEFY
pub struct BeefyDeps<AuthorityId: AuthorityIdBound> {
/// Receives notifications about finality proof events from BEEFY.
pub beefy_finality_proof_stream: BeefyVersionedFinalityProofStream<Block, AuthorityId>,
/// Receives notifications about best block events from BEEFY.
pub beefy_best_block_stream: BeefyBestBlockStream<Block>,
/// Executor to drive the subscription manager in the BEEFY RPC handler.
pub subscription_executor: sc_rpc::SubscriptionTaskExecutor,
}

/// Full client dependencies.
pub struct FullDeps<C, P, B, T> {
pub struct FullDeps<C, P, B, T, AuthorityId: AuthorityIdBound> {
/// The client instance to use.
pub client: Arc<C>,
/// Transaction pool instance.
pub pool: Arc<P>,
/// GRANDPA specific dependencies.
pub grandpa: GrandpaDeps<B>,
/// BEEFY specific dependencies.
pub beefy: BeefyDeps<AuthorityId>,
/// Data sources.
pub data_sources: DataSources,
/// Source of system time
pub time_source: Arc<T>,
}

/// Instantiate all full RPC extensions.
pub fn create_full<C, P, B, T>(
deps: FullDeps<C, P, B, T>,
pub fn create_full<C, P, B, T, AuthorityId: AuthorityIdBound>(
deps: FullDeps<C, P, B, T, AuthorityId>,
) -> Result<RpcModule<()>, Box<dyn std::error::Error + Send + Sync>>
where
C: ProvideRuntimeApi<Block>,
Expand Down Expand Up @@ -92,10 +109,11 @@ where
T: TimeSource + Send + Sync + 'static,
{
use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
use sc_consensus_beefy_rpc::BeefyApiServer;
use substrate_frame_rpc_system::{System, SystemApiServer};

let mut module = RpcModule::new(());
let FullDeps { client, pool, grandpa, data_sources, time_source } = deps;
let FullDeps { client, pool, grandpa, beefy, data_sources, time_source } = deps;

module.merge(System::new(client.clone(), pool.clone()).into_rpc())?;
module.merge(TransactionPayment::new(client.clone()).into_rpc())?;
Expand Down Expand Up @@ -136,6 +154,15 @@ where
.into_rpc(),
)?;

module.merge(
Beefy::<Block, AuthorityId>::new(
beefy.beefy_finality_proof_stream,
beefy.beefy_best_block_stream,
beefy.subscription_executor,
)?
.into_rpc(),
)?;

// Extend this RPC with a custom API by using the following syntax.
// `YourRpcStruct` should have a reference to a client, which is needed
// to call into the runtime.
Expand Down
121 changes: 113 additions & 8 deletions demo/node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@

use crate::data_sources::DataSources;
use crate::inherent_data::{CreateInherentDataConfig, ProposalCIDP, VerifierCIDP};
use crate::rpc::GrandpaDeps;
use crate::rpc::{BeefyDeps, GrandpaDeps};
use authority_selection_inherents::AuthoritySelectionDataSource;
use partner_chains_data_source_metrics::{McFollowerMetrics, register_metrics_warn_errors};
use partner_chains_demo_runtime::{self, RuntimeApi, opaque::Block};
use sc_client_api::BlockBackend;
use sc_consensus_aura::{ImportQueueParams, SlotProportion, StartAuraParams};
use sc_consensus_beefy::{BeefyRPCLinks, BeefyVoterLinks};
use sc_consensus_grandpa::SharedVoterState;
pub use sc_executor::WasmExecutor;
use sc_partner_chains_consensus_aura::import_queue as partner_chains_aura_import_queue;
use sc_rpc::SubscriptionTaskExecutor;
use sc_service::{Configuration, TaskManager, WarpSyncConfig, error::Error as ServiceError};
use sc_telemetry::{Telemetry, TelemetryWorker};
use sc_transaction_pool_api::OffchainTransactionPoolFactory;
use sidechain_domain::mainchain_epoch::MainchainEpochConfig;
use sidechain_mc_hash::McHashInherentDigest;
use sp_consensus_aura::sr25519::AuthorityPair as AuraPair;
use sp_consensus_beefy::ecdsa_crypto::AuthorityId as BeefyId;

use sp_partner_chains_consensus_aura::block_proposal::PartnerChainsProposerFactory;
use sp_runtime::traits::Block as BlockT;
use std::{sync::Arc, time::Duration};
Expand Down Expand Up @@ -76,6 +80,8 @@ pub fn new_partial(
Option<Telemetry>,
DataSources,
Option<McFollowerMetrics>,
BeefyVoterLinks<Block, BeefyId>,
BeefyRPCLinks<Block, BeefyId>,
),
>,
ServiceError,
Expand Down Expand Up @@ -133,6 +139,15 @@ pub fn new_partial(
select_chain.clone(),
telemetry.as_ref().map(|x| x.handle()),
)?;
let justification_import = grandpa_block_import.clone();

let (block_import, beefy_voter_links, beefy_rpc_links) =
sc_consensus_beefy::beefy_block_import_and_links(
grandpa_block_import.clone(),
backend.clone(),
client.clone(),
config.prometheus_registry().cloned(),
);

let sc_slot_config = sidechain_slots::runtime_api_client::slot_config(&*client)
.map_err(sp_blockchain::Error::from)?;
Expand All @@ -151,8 +166,8 @@ pub fn new_partial(
_,
McHashInherentDigest,
>(ImportQueueParams {
block_import: grandpa_block_import.clone(),
justification_import: Some(Box::new(grandpa_block_import.clone())),
block_import: block_import.clone(),
justification_import: Some(Box::new(justification_import)),
client: client.clone(),
create_inherent_data_providers: VerifierCIDP::new(
inherent_config,
Expand All @@ -178,7 +193,15 @@ pub fn new_partial(
keystore_container,
select_chain,
transaction_pool,
other: (grandpa_block_import, grandpa_link, telemetry, data_sources, mc_follower_metrics),
other: (
grandpa_block_import,
grandpa_link,
telemetry,
data_sources,
mc_follower_metrics,
beefy_voter_links,
beefy_rpc_links,
),
})
}

Expand Down Expand Up @@ -210,7 +233,16 @@ pub async fn new_full_base<Network: sc_network::NetworkBackend<Block, <Block as
keystore_container,
select_chain,
transaction_pool,
other: (block_import, grandpa_link, mut telemetry, data_sources, _),
other:
(
block_import,
grandpa_link,
mut telemetry,
data_sources,
_,
beefy_voter_links,
beefy_rpc_links,
),
} = new_partial(&config)?;

let metrics = Network::register_notification_metrics(config.prometheus_registry());
Expand All @@ -223,7 +255,10 @@ pub async fn new_full_base<Network: sc_network::NetworkBackend<Block, <Block as
&client.block_hash(0).ok().flatten().expect("Genesis block exists; qed"),
&config.chain_spec,
);
let genesis_hash = client.chain_info().genesis_hash;
let peer_store_handle = net_config.peer_store_handle();
let prometheus_registry = config.prometheus_registry().cloned();

let (grandpa_protocol_config, grandpa_notification_service) =
sc_consensus_grandpa::grandpa_peers_set_config::<_, Network>(
grandpa_protocol_name.clone(),
Expand All @@ -232,6 +267,29 @@ pub async fn new_full_base<Network: sc_network::NetworkBackend<Block, <Block as
);
net_config.add_notification_protocol(grandpa_protocol_config);

let beefy_gossip_proto_name =
sc_consensus_beefy::gossip_protocol_name(&genesis_hash, config.chain_spec.fork_id());
// `beefy_on_demand_justifications_handler` is given to `beefy-gadget` task to be run,
// while `beefy_req_resp_cfg` is added to `config.network.request_response_protocols`.
let (beefy_on_demand_justifications_handler, beefy_req_resp_cfg) =
sc_consensus_beefy::communication::request_response::BeefyJustifsRequestHandler::new::<
_,
Network,
>(&genesis_hash, config.chain_spec.fork_id(), client.clone(), prometheus_registry.clone());
let beefy_notification_service = {
let (beefy_notification_config, beefy_notification_service) =
sc_consensus_beefy::communication::beefy_peers_set_config::<_, Network>(
beefy_gossip_proto_name.clone(),
metrics.clone(),
Arc::clone(&peer_store_handle),
);

net_config.add_notification_protocol(beefy_notification_config);
net_config.add_request_response_protocol(beefy_req_resp_cfg);
// For now we always initialize it
Some(beefy_notification_service)
};

let warp_sync = Arc::new(sc_consensus_grandpa::warp_proof::NetworkProvider::new(
backend.clone(),
grandpa_link.shared_authority_set().clone(),
Expand Down Expand Up @@ -269,21 +327,27 @@ pub async fn new_full_base<Network: sc_network::NetworkBackend<Block, <Block as
let justification_stream = grandpa_link.justification_stream();
let data_sources = data_sources.clone();

move |subscription_executor| {
move |subscription_executor: SubscriptionTaskExecutor| {
let grandpa = GrandpaDeps {
shared_voter_state: shared_voter_state.clone(),
shared_authority_set: shared_authority_set.clone(),
justification_stream: justification_stream.clone(),
subscription_executor,
subscription_executor: subscription_executor.clone(),
finality_provider: sc_consensus_grandpa::FinalityProofProvider::new_for_service(
backend.clone(),
Some(shared_authority_set.clone()),
),
};
let beefy = BeefyDeps::<BeefyId> {
beefy_finality_proof_stream: beefy_rpc_links.from_voter_justif_stream.clone(),
beefy_best_block_stream: beefy_rpc_links.from_voter_best_beefy_stream.clone(),
subscription_executor,
};
let deps = crate::rpc::FullDeps {
client: client.clone(),
pool: pool.clone(),
grandpa,
beefy,
data_sources: data_sources.clone(),
time_source: Arc::new(SystemTimeSource),
};
Expand All @@ -298,12 +362,13 @@ pub async fn new_full_base<Network: sc_network::NetworkBackend<Block, <Block as
task_manager: &mut task_manager,
transaction_pool: transaction_pool.clone(),
rpc_builder: Box::new(rpc_extensions_builder),
backend,
backend: backend.clone(),
system_rpc_tx,
tx_handler_controller,
sync_service: sync_service.clone(),
config,
telemetry: telemetry.as_mut(),
tracing_execute_block: None,
})?;

if role.is_authority() {
Expand Down Expand Up @@ -370,6 +435,46 @@ pub async fn new_full_base<Network: sc_network::NetworkBackend<Block, <Block as
.spawn_blocking("aura", Some("block-authoring"), aura);
}

// if the node isn't actively participating in consensus then it doesn't
// need a keystore, regardless of which protocol we use below.
let keystore_opt = if role.is_authority() { Some(keystore_container.keystore()) } else { None };

// beefy is enabled if its notification service exists
if let Some(notification_service) = beefy_notification_service {
let justifications_protocol_name = beefy_on_demand_justifications_handler.protocol_name();
let network_params = sc_consensus_beefy::BeefyNetworkParams {
network: Arc::new(network.clone()),
sync: sync_service.clone(),
gossip_protocol_name: beefy_gossip_proto_name,
justifications_protocol_name,
notification_service,
_phantom: core::marker::PhantomData::<Block>,
};
let payload_provider = sp_consensus_beefy::mmr::MmrRootProvider::new(client.clone());
let beefy_params = sc_consensus_beefy::BeefyParams {
client: client.clone(),
backend: backend.clone(),
payload_provider,
runtime: client.clone(),
key_store: keystore_opt.clone(),
network_params,
min_block_delta: 8,
prometheus_registry: prometheus_registry.clone(),
links: beefy_voter_links,
on_demand_justifications_handler: beefy_on_demand_justifications_handler,
is_authority: role.is_authority(),
};

let gadget =
sc_consensus_beefy::start_beefy_gadget::<_, _, _, _, _, _, _, BeefyId>(beefy_params);

// BEEFY is part of consensus, if it fails we'll bring the node down with it to make
// sure it is noticed.
task_manager
.spawn_essential_handle()
.spawn_blocking("beefy-gadget", None, gadget);
}

if enable_grandpa {
// if the node isn't actively participating in consensus then it doesn't
// need a keystore, regardless of which protocol we use below.
Expand Down
Loading
Loading