diff --git a/Cargo.lock b/Cargo.lock index 82942ab64f..76d8bf28a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2856,6 +2856,21 @@ dependencies = [ "sp-timestamp", ] +[[package]] +name = "fc-babe" +version = "1.0.0-dev" +dependencies = [ + "fc-rpc", + "sc-client-api", + "sc-consensus-babe", + "sp-api", + "sp-blockchain", + "sp-consensus-babe", + "sp-inherents", + "sp-runtime", + "sp-timestamp", +] + [[package]] name = "fc-cli" version = "1.0.0-dev" diff --git a/Cargo.toml b/Cargo.toml index c9e0f8066c..c78247461a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ members = [ "frame/hotfix-sufficients", "client/api", "client/aura", + "client/babe", "client/consensus", "client/rpc-core", "client/rpc", @@ -91,6 +92,7 @@ sc-client-api = { git = "https://github.com/paritytech/polkadot-sdk", tag = "pol sc-client-db = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6", default-features = false } sc-consensus = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6" } sc-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6" } +sc-consensus-babe = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6" } sc-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6" } sc-consensus-manual-seal = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6" } sc-executor = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6" } @@ -112,6 +114,7 @@ sp-block-builder = { git = "https://github.com/paritytech/polkadot-sdk", tag = " sp-blockchain = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6", default-features = false } sp-consensus = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6", default-features = false } sp-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6", default-features = false } +sp-consensus-babe = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6", default-features = false } sp-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6", default-features = false } sp-core = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6", default-features = false } sp-crypto-hashing = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2503-6", default-features = false } @@ -176,6 +179,7 @@ ark-std = { version = "0.4.0", default-features = false } # Frontier Client fc-api = { path = "client/api" } fc-aura = { path = "client/aura" } +fc-babe = { path = "client/babe" } fc-cli = { path = "client/cli", default-features = false } fc-consensus = { path = "client/consensus" } fc-db = { path = "client/db", default-features = false } diff --git a/client/babe/Cargo.toml b/client/babe/Cargo.toml new file mode 100644 index 0000000000..0bebd13efc --- /dev/null +++ b/client/babe/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "fc-babe" +version = "1.0.0-dev" +authors = { workspace = true } +edition = { workspace = true } +license = "GPL-3.0-or-later WITH Classpath-exception-2.0" +repository = { workspace = true } +description = "Babe consensus data provider for pending runtime calls" + +[dependencies] +# Substrate +sc-client-api = { workspace = true } +sc-consensus-babe = { workspace = true } +sp-api = { workspace = true } +sp-blockchain = { workspace = true } +sp-consensus-babe = { workspace = true } +sp-inherents = { workspace = true } +sp-runtime = { workspace = true } +sp-timestamp = { workspace = true } +# Frontier +fc-rpc = { workspace = true } diff --git a/client/babe/src/lib.rs b/client/babe/src/lib.rs new file mode 100644 index 0000000000..817abf1581 --- /dev/null +++ b/client/babe/src/lib.rs @@ -0,0 +1,60 @@ +use std::{marker::PhantomData, sync::Arc}; + +use fc_rpc::pending::ConsensusDataProvider; +use sc_client_api::{AuxStore, UsageProvider}; +use sp_api::ProvideRuntimeApi; +use sp_blockchain::Error; +use sp_consensus_babe::{digests::CompatibleDigestItem, BabeApi, BabeConfiguration, Slot}; +use sp_inherents::InherentData; +use sp_runtime::{traits::Block as BlockT, Digest, DigestItem}; +use sp_timestamp::TimestampInherentData; + +pub struct BabeConsensusDataProvider { + babe_config: BabeConfiguration, + _phantom: PhantomData<(B, C)>, +} + +impl BabeConsensusDataProvider +where + B: BlockT, + C: AuxStore + ProvideRuntimeApi + UsageProvider, + C::Api: BabeApi, +{ + /// Creates a new instance of the [`BabeConsensusDataProvider`], requires that `client` + /// implements [`sp_consensus_babe::BabeApi`] + pub fn new(client: Arc) -> Result { + let babe_config = sc_consensus_babe::configuration(&*client)?; + Ok(Self { + babe_config, + _phantom: PhantomData, + }) + } +} + +impl ConsensusDataProvider for BabeConsensusDataProvider { + fn create_digest( + &self, + _parent: &B::Header, + data: &InherentData, + ) -> Result { + let timestamp = data + .timestamp_inherent_data()? + .expect("Timestamp is always present; qed"); + + let slot_duration = self.babe_config.slot_duration(); + let slot = Slot::from_timestamp(timestamp, slot_duration); + + let digest_item = ::babe_pre_digest( + sp_consensus_babe::digests::PreDigest::SecondaryPlain( + sp_consensus_babe::digests::SecondaryPlainPreDigest { + slot, + authority_index: 0, // Use first authority for pending blocks + }, + ), + ); + + Ok(Digest { + logs: vec![digest_item], + }) + } +}