diff --git a/Cargo.lock b/Cargo.lock index 064c92d..1f60669 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4532,6 +4532,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", + "sp-api 4.0.0-dev", "sp-core 7.0.0", "sp-io 7.0.0", "sp-runtime 7.0.0", @@ -4577,6 +4578,60 @@ dependencies = [ "rust-kzg-blst", ] +[[package]] +name = "melodot-node" +version = "0.0.1" +dependencies = [ + "clap 4.4.1", + "frame-benchmarking 4.0.0-dev", + "frame-benchmarking-cli", + "frame-system 4.0.0-dev", + "futures", + "jsonrpsee", + "melo-core-primitives", + "melodot-runtime", + "pallet-transaction-payment", + "pallet-transaction-payment-rpc", + "sc-authority-discovery", + "sc-basic-authorship", + "sc-chain-spec", + "sc-cli", + "sc-client-api", + "sc-consensus", + "sc-consensus-babe", + "sc-consensus-babe-rpc", + "sc-consensus-grandpa", + "sc-consensus-grandpa-rpc", + "sc-executor", + "sc-keystore", + "sc-network", + "sc-network-das", + "sc-rpc", + "sc-rpc-api", + "sc-service", + "sc-sync-state-rpc", + "sc-telemetry", + "sc-transaction-pool", + "sc-transaction-pool-api", + "sp-api 4.0.0-dev", + "sp-authority-discovery", + "sp-block-builder", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-consensus-grandpa", + "sp-core 7.0.0", + "sp-inherents 4.0.0-dev", + "sp-io 7.0.0", + "sp-keyring", + "sp-keystore 0.13.0", + "sp-runtime 7.0.0", + "sp-timestamp 4.0.0-dev", + "substrate-build-script-utils", + "substrate-frame-rpc-system", + "try-runtime-cli", +] + [[package]] name = "melodot-runtime" version = "0.0.1" @@ -4592,6 +4647,7 @@ dependencies = [ "frame-try-runtime", "melo-auto-config", "melo-core-primitives", + "melo-das-primitives", "node-primitives", "pallet-authority-discovery", "pallet-authorship", @@ -4620,6 +4676,7 @@ dependencies = [ "pallet-transaction-payment", "pallet-transaction-payment-rpc-runtime-api", "pallet-treasury", + "pallet-utility", "parity-scale-codec", "scale-info", "sp-api 4.0.0-dev", @@ -5040,50 +5097,6 @@ dependencies = [ "sp-runtime 7.0.0", ] -[[package]] -name = "node-template" -version = "4.0.0-dev" -dependencies = [ - "clap 4.4.1", - "frame-benchmarking 4.0.0-dev", - "frame-benchmarking-cli", - "frame-system 4.0.0-dev", - "futures", - "jsonrpsee", - "melodot-runtime", - "pallet-transaction-payment", - "pallet-transaction-payment-rpc", - "sc-basic-authorship", - "sc-cli", - "sc-client-api", - "sc-consensus", - "sc-consensus-aura", - "sc-consensus-grandpa", - "sc-executor", - "sc-keystore", - "sc-rpc", - "sc-rpc-api", - "sc-service", - "sc-telemetry", - "sc-transaction-pool", - "sc-transaction-pool-api", - "sp-api 4.0.0-dev", - "sp-block-builder", - "sp-blockchain", - "sp-consensus", - "sp-consensus-aura", - "sp-consensus-grandpa", - "sp-core 7.0.0", - "sp-inherents 4.0.0-dev", - "sp-io 7.0.0", - "sp-keyring", - "sp-runtime 7.0.0", - "sp-timestamp 4.0.0-dev", - "substrate-build-script-utils", - "substrate-frame-rpc-system", - "try-runtime-cli", -] - [[package]] name = "nohash-hasher" version = "0.2.0" @@ -5830,6 +5843,22 @@ dependencies = [ "sp-std 5.0.0", ] +[[package]] +name = "pallet-utility" +version = "4.0.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" +dependencies = [ + "frame-benchmarking 4.0.0-dev", + "frame-support 4.0.0-dev", + "frame-system 4.0.0-dev", + "parity-scale-codec", + "scale-info", + "sp-core 7.0.0", + "sp-io 7.0.0", + "sp-runtime 7.0.0", + "sp-std 5.0.0", +] + [[package]] name = "parity-db" version = "0.4.10" @@ -7130,6 +7159,34 @@ dependencies = [ "thiserror", ] +[[package]] +name = "sc-authority-discovery" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" +dependencies = [ + "async-trait", + "futures", + "futures-timer", + "ip_network", + "libp2p", + "log", + "parity-scale-codec", + "prost", + "prost-build", + "rand 0.8.5", + "sc-client-api", + "sc-network", + "sc-network-common", + "sp-api 4.0.0-dev", + "sp-authority-discovery", + "sp-blockchain", + "sp-core 7.0.0", + "sp-keystore 0.13.0", + "sp-runtime 7.0.0", + "substrate-prometheus-endpoint", + "thiserror", +] + [[package]] name = "sc-basic-authorship" version = "0.10.0-dev" @@ -7316,25 +7373,32 @@ dependencies = [ ] [[package]] -name = "sc-consensus-aura" +name = "sc-consensus-babe" version = "0.10.0-dev" source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" dependencies = [ "async-trait", + "fork-tree", "futures", "log", + "num-bigint", + "num-rational", + "num-traits", "parity-scale-codec", - "sc-block-builder", + "parking_lot 0.12.1", "sc-client-api", "sc-consensus", + "sc-consensus-epochs", "sc-consensus-slots", + "sc-keystore", "sc-telemetry", + "scale-info", "sp-api 4.0.0-dev", "sp-application-crypto 7.0.0", "sp-block-builder", "sp-blockchain", "sp-consensus", - "sp-consensus-aura", + "sp-consensus-babe", "sp-consensus-slots", "sp-core 7.0.0", "sp-inherents 4.0.0-dev", @@ -7344,6 +7408,41 @@ dependencies = [ "thiserror", ] +[[package]] +name = "sc-consensus-babe-rpc" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" +dependencies = [ + "futures", + "jsonrpsee", + "sc-consensus-babe", + "sc-consensus-epochs", + "sc-rpc-api", + "serde", + "sp-api 4.0.0-dev", + "sp-application-crypto 7.0.0", + "sp-blockchain", + "sp-consensus", + "sp-consensus-babe", + "sp-core 7.0.0", + "sp-keystore 0.13.0", + "sp-runtime 7.0.0", + "thiserror", +] + +[[package]] +name = "sc-consensus-epochs" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" +dependencies = [ + "fork-tree", + "parity-scale-codec", + "sc-client-api", + "sc-consensus", + "sp-blockchain", + "sp-runtime 7.0.0", +] + [[package]] name = "sc-consensus-grandpa" version = "0.10.0-dev" @@ -7384,6 +7483,26 @@ dependencies = [ "thiserror", ] +[[package]] +name = "sc-consensus-grandpa-rpc" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" +dependencies = [ + "finality-grandpa", + "futures", + "jsonrpsee", + "log", + "parity-scale-codec", + "sc-client-api", + "sc-consensus-grandpa", + "sc-rpc", + "serde", + "sp-blockchain", + "sp-core 7.0.0", + "sp-runtime 7.0.0", + "thiserror", +] + [[package]] name = "sc-consensus-slots" version = "0.10.0-dev" @@ -7613,8 +7732,11 @@ dependencies = [ "sc-network", "sc-transaction-pool", "sc-transaction-pool-api", + "sp-api 4.0.0-dev", + "sp-blockchain", "sp-core 7.0.0", "sp-runtime 7.0.0", + "tracing", ] [[package]] @@ -7948,6 +8070,25 @@ dependencies = [ "tokio", ] +[[package]] +name = "sc-sync-state-rpc" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/substrate.git?branch=polkadot-v0.9.42#ff24c60ac7d9f87727ecdd0ded9a80c56e4f4b65" +dependencies = [ + "jsonrpsee", + "parity-scale-codec", + "sc-chain-spec", + "sc-client-api", + "sc-consensus-babe", + "sc-consensus-epochs", + "sc-consensus-grandpa", + "serde", + "serde_json", + "sp-blockchain", + "sp-runtime 7.0.0", + "thiserror", +] + [[package]] name = "sc-sysinfo" version = "6.0.0-dev" diff --git a/crates/core-primitives/Cargo.toml b/crates/core-primitives/Cargo.toml index 389ec14..b5b4eb4 100644 --- a/crates/core-primitives/Cargo.toml +++ b/crates/core-primitives/Cargo.toml @@ -21,6 +21,7 @@ sp-core = { version = "7.0.0", default-features = false, git = "https://github.c sp-std = { version = "5.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sp-runtime = { version = "7.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sp-io = { version = "7.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-api = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } # sc-network = { version = "0.10.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } [features] diff --git a/crates/core-primitives/src/traits.rs b/crates/core-primitives/src/traits.rs index b8bd328..e4adadf 100644 --- a/crates/core-primitives/src/traits.rs +++ b/crates/core-primitives/src/traits.rs @@ -12,8 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -use melo_das_primitives::KZGCommitment; use crate::{Digest, HeaderExtension, Vec}; +use melo_das_primitives::{KZGCommitment, KZGProof}; +use sp_core::H256; pub trait ExtendedHeader { /// Header number. @@ -32,29 +33,39 @@ pub trait ExtendedHeader { extension: HeaderExtension, ) -> Self; - /// Returns the header extension. + /// Returns the header extension. fn extension(&self) -> &HeaderExtension; - /// Set the header extension. + /// Set the header extension. fn set_extension(&mut self, extension: HeaderExtension); - /// Set the commitment of root. - fn set_commitments(&mut self, commitment_set: &[KZGCommitment]); + /// Set the commitment of root. + fn set_commitments(&mut self, commitment_set: &[KZGCommitment]); - /// Returns the commitments. - fn commitments(&self) -> Option>; + /// Returns the commitments. + fn commitments(&self) -> Option>; - /// Returns the commitments set bytes. - fn commitments_bytes(&self) -> &[u8]; + /// Returns the commitments set bytes. + fn commitments_bytes(&self) -> &[u8]; - /// Returns the number of columns. - fn col_num(&self) -> Option; + /// Returns the number of columns. + fn col_num(&self) -> Option; } pub trait HeaderCommitList { - /// Returns a list of the latest confirmed commitments available for the Blob Matrix. - /// - /// Note that they are not related to data availability, but rather to the validator's + /// Returns a list of the latest confirmed commitments available for the Blob Matrix. + /// + /// Note that they are not related to data availability, but rather to the validator's /// initial confirmation of the probability of availability. - fn last() -> Vec; -} \ No newline at end of file + fn last() -> Vec; +} + +sp_api::decl_runtime_apis! { + /// Extracts the `data` field from some types of extrinsics. + pub trait Extractor { + fn extract( + extrinsic: &Vec, + // (data_hash, bytes_len, commitments, proofs) + ) -> Option, Vec)>>; +} +} diff --git a/crates/network-das/Cargo.toml b/crates/network-das/Cargo.toml index d553811..7ad0411 100644 --- a/crates/network-das/Cargo.toml +++ b/crates/network-das/Cargo.toml @@ -16,14 +16,17 @@ melo-core-primitives = { version = "0.1.0", default-features = false, path = ".. async-trait = "0.1.56" futures = "0.3.21" +tracing = "0.1.37" -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sp-core = { version = "7.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sp-runtime = { version = "7.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-network = { version = "0.10.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -node-primitives = { version = "2.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +frame-system = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-transaction-pool = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-network = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +node-primitives = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-api = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-blockchain = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } [features] default = ["std"] diff --git a/crates/network-das/src/dht_work.rs b/crates/network-das/src/dht_work.rs index 5c96462..98c080f 100644 --- a/crates/network-das/src/dht_work.rs +++ b/crates/network-das/src/dht_work.rs @@ -14,7 +14,6 @@ #![cfg_attr(not(feature = "std"), no_std)] -use futures::Future; use futures::{FutureExt, Stream, StreamExt}; use melo_das_primitives::blob::Blob; use melo_das_primitives::config::FIELD_ELEMENTS_PER_BLOB; @@ -45,82 +44,81 @@ where Worker { client, network, dht_event_rx } } - pub async fn run(mut self, start: FStart, handler: FHandler) + pub async fn run(mut self, start: FStart) where - FStart: Fn() -> Fut + Send + Sync + 'static, - Fut: Future + Send + 'static, - FHandler: Fn(DhtEvent) -> Fut + Send + Sync + 'static, + FStart: Fn(), { loop { start(); futures::select! { event = self.dht_event_rx.next().fuse() => { if let Some(event) = event { - handler(event).await; + Self::handle_dht_event(event).await; } }, } } } -} -pub fn handle_dht_event(event: DhtEvent) { - match event { - DhtEvent::ValueFound(v) => { - handle_dht_value_found_event(v); - }, - DhtEvent::ValueNotFound(key) => handle_dht_value_not_found_event(key), - _ => {}, + async fn handle_dht_event(event: DhtEvent) { + match event { + DhtEvent::ValueFound(v) => { + Self::handle_dht_value_found_event(v); + }, + DhtEvent::ValueNotFound(key) => Self::handle_dht_value_not_found_event(key), + _ => {}, + } } -} -pub fn handle_dht_value_found_event(values: Vec<(KademliaKey, Vec)>) { - for (key, value) in values { + fn handle_dht_value_found_event(values: Vec<(KademliaKey, Vec)>) { + for (key, value) in values { + let maybe_sidercar = Sidercar::from_local(key.as_ref()); + match maybe_sidercar { + Some(sidercar) => { + if sidercar.status.is_none() { + let data_hash = Sidercar::calculate_id(&value); + let mut new_sidercar = sidercar.clone(); + if data_hash != sidercar.metadata.blobs_hash.as_bytes() { + new_sidercar.status = Some(SidercarStatus::ProofError); + } else { + let kzg = KZG::default_embedded(); + // TODO bytes to blobs + let blobs = bytes_vec_to_blobs(&[value.clone()], 1).unwrap(); + let encoding_valid = Blob::verify_batch( + &blobs, + &sidercar.metadata.commitments, + &sidercar.metadata.proofs, + &kzg, + FIELD_ELEMENTS_PER_BLOB, + ) + .unwrap(); + if encoding_valid { + new_sidercar.blobs = Some(value.clone()); + new_sidercar.status = Some(SidercarStatus::Success); + } else { + new_sidercar.status = Some(SidercarStatus::ProofError); + } + } + new_sidercar.save_to_local(); + } + }, + None => {}, + } + } + } + + fn handle_dht_value_not_found_event(key: KademliaKey) { let maybe_sidercar = Sidercar::from_local(key.as_ref()); match maybe_sidercar { Some(sidercar) => { if sidercar.status.is_none() { - let data_hash = Sidercar::calculate_id(&value); let mut new_sidercar = sidercar.clone(); - if data_hash != sidercar.metadata.blobs_hash.as_bytes() { - new_sidercar.status = Some(SidercarStatus::ProofError); - } else { - let kzg = KZG::default_embedded(); - // TODO bytes to blobs - let blobs = bytes_vec_to_blobs(&[value.clone()], 1).unwrap(); - let encoding_valid = Blob::verify_batch( - &blobs, - &sidercar.metadata.commitments, - &sidercar.metadata.proofs, - &kzg, - FIELD_ELEMENTS_PER_BLOB, - ) - .unwrap(); - if encoding_valid { - new_sidercar.blobs = Some(value.clone()); - new_sidercar.status = Some(SidercarStatus::Success); - } else { - new_sidercar.status = Some(SidercarStatus::ProofError); - } - } + new_sidercar.status = Some(SidercarStatus::NotFound); new_sidercar.save_to_local(); } }, None => {}, } } -} - -fn handle_dht_value_not_found_event(key: KademliaKey) { - let maybe_sidercar = Sidercar::from_local(key.as_ref()); - match maybe_sidercar { - Some(sidercar) => { - if sidercar.status.is_none() { - let mut new_sidercar = sidercar.clone(); - new_sidercar.status = Some(SidercarStatus::NotFound); - new_sidercar.save_to_local(); - } - }, - None => {}, - } -} + +} \ No newline at end of file diff --git a/crates/network-das/src/tx_pool_listener.rs b/crates/network-das/src/tx_pool_listener.rs index fa5de02..7241114 100644 --- a/crates/network-das/src/tx_pool_listener.rs +++ b/crates/network-das/src/tx_pool_listener.rs @@ -12,40 +12,43 @@ // See the License for the specific language governing permissions and // limitations under the License. -use frame_system::Config; use futures::StreamExt; -use melo_das_primitives::crypto::{KZGCommitment, KZGProof}; +use melo_core_primitives::{traits::Extractor, Encode}; use sc_network::{KademliaKey, NetworkDHTProvider}; use sc_transaction_pool_api::{InPoolTransaction, TransactionPool}; -use sp_core::H256; +use sp_api::ProvideRuntimeApi; +use sp_blockchain::HeaderBackend; use sp_runtime::traits::Block as BlockT; -use sp_runtime::traits::Extrinsic; use std::sync::Arc; -use crate::AccountId; +const LOG_TARGET: &str = "tx_pool_listener"; + +use crate::{NetworkProvider, Sidercar, SidercarMetadata}; fn sidercar_kademlia_key(sidercar: &Sidercar) -> KademliaKey { KademliaKey::from(Vec::from(sidercar.id())) } -use crate::{NetworkProvider, Sidercar, SidercarMetadata}; - -/// Extracts the `data` field from some types of extrinsics. -pub trait Extractor { - fn extract( - app_ext: T, - ) -> Option<(H256, u32, u32, Vec, Vec, AccountId)>; +#[derive(Clone)] +pub struct TPListenerParams { + pub client: Arc, + pub network: Arc, + pub transaction_pool: Arc, } -pub async fn process_tx_pool_notifications( - transaction_pool: TP, - network: Arc, +pub async fn start_tx_pool_listener( + TPListenerParams { client, network, transaction_pool }: TPListenerParams, ) where - B: BlockT + 'static, - Network: NetworkProvider, - TP: TransactionPool, - C: Config + Send + Sync + Extractor, + Network: NetworkProvider + 'static, + TP: TransactionPool + 'static, + B: BlockT + Send + Sync + 'static, + Client: HeaderBackend + ProvideRuntimeApi, + Client::Api: Extractor, { + tracing::info!( + target: LOG_TARGET, + "Starting transaction pool listener.", + ); // Obtain the import notification event stream from the transaction pool let mut import_notification_stream = transaction_pool.import_notification_stream(); @@ -53,34 +56,63 @@ pub async fn process_tx_pool_notifications( while let Some(notification) = import_notification_stream.next().await { match transaction_pool.ready_transaction(¬ification) { Some(transaction) => { - let extrinsic = transaction.data(); - if let Some((data_hash, bytes_len, _, commitments, proofs, _)) = - C::extract(extrinsic.clone()) - { - let metadata = SidercarMetadata { - data_len: bytes_len, - blobs_hash: data_hash, - commitments, - proofs, - }; + // TODO: Can we avoid decoding the extrinsic here? + let encoded = transaction.data().encode(); + let at = client.info().best_hash; + match client.runtime_api().extract(at, &encoded) { + Ok(res) => match res { + Some(data) => { + data.into_iter().for_each( + |(data_hash, bytes_len, commitments, proofs)| { + tracing::debug!( + target: LOG_TARGET, + "New blob transaction found. Hash: {:?}", data_hash, + ); + + let metadata = SidercarMetadata { + data_len: bytes_len, + blobs_hash: data_hash, + commitments, + proofs, + }; - let fetch_value_from_network = |sidercar: &Sidercar| { - network.get_value(&sidercar_kademlia_key(sidercar)); - }; + let fetch_value_from_network = |sidercar: &Sidercar| { + network.get_value(&sidercar_kademlia_key(sidercar)); + }; - match Sidercar::from_local(&metadata.id()) { - Some(sidercar) => { - if sidercar.status.is_none() { - fetch_value_from_network(&sidercar); - } + match Sidercar::from_local(&metadata.id()) { + Some(sidercar) => { + if sidercar.status.is_none() { + fetch_value_from_network(&sidercar); + } + }, + None => { + let sidercar = + Sidercar { blobs: None, metadata, status: None }; + sidercar.save_to_local(); + fetch_value_from_network(&sidercar); + }, + } + }, + ); }, None => { - let sidercar = Sidercar { blobs: None, metadata, status: None }; - sidercar.save_to_local(); - fetch_value_from_network(&sidercar); + tracing::debug!( + target: LOG_TARGET, + "Decoding of extrinsic failed. Transaction: {:?}", + transaction.hash(), + ); }, - } - } + }, + Err(err) => { + tracing::debug!( + target: LOG_TARGET, + "Failed to extract data from extrinsic. Transaction: {:?}. Error: {:?}", + transaction.hash(), + err, + ); + }, + }; }, None => {}, } diff --git a/node/Cargo.toml b/node/Cargo.toml index a9746a1..f9dc99c 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -1,71 +1,86 @@ [package] -name = "node-template" -version = "4.0.0-dev" -description = "A fresh FRAME-based Substrate node, ready for hacking." -authors = ["Substrate DevHub "] -homepage = "https://substrate.io/" +name = "melodot-node" +version = "0.0.1" +description = "Melodot Node" +authors = ["DKLee "] +repository = "https://github.com/ZeroDAO/melodot" +keywords = ["substrate"] edition = "2021" -license = "MIT-0" -publish = false -repository = "https://github.com/substrate-developer-hub/substrate-node-template/" +license = "Apache-2.0" build = "build.rs" [package.metadata.docs.rs] targets = ["x86_64-unknown-linux-gnu"] [[bin]] -name = "node-template" +name = "melodot-node" [dependencies] clap = { version = "4.0.9", features = ["derive"] } futures = { version = "0.3.21", features = ["thread-pool"]} -sc-cli = { version = "0.10.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sp-core = { version = "7.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-executor = { version = "0.10.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-service = { version = "0.10.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-telemetry = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-keystore = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-transaction-pool-api = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-consensus-aura = { version = "0.10.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sp-consensus-aura = { version = "0.10.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-network = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" } +sc-sync-state-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" } +sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" } + +sc-cli = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-executor = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-service = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-telemetry = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-keystore = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-transaction-pool = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } + +sc-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" } +sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" } +sc-consensus-babe-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" } + sp-consensus = { version = "0.10.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } sc-consensus = { version = "0.10.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-consensus-grandpa = { version = "0.10.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sp-consensus-grandpa = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-client-api = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sp-runtime = { version = "7.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sp-io = { version = "7.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sp-timestamp = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sp-inherents = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sp-keyring = { version = "7.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -frame-system = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -pallet-transaction-payment = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } + +sc-consensus-grandpa = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-consensus-grandpa = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-consensus-grandpa-rpc = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" } + +sc-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" } +sp-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" } + +sp-keystore = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42" } +sc-client-api = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-timestamp = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-inherents = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-keyring = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +frame-system = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +pallet-transaction-payment = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } # These dependencies are used for the node template's RPCs -jsonrpsee = { version = "0.16.2", features = ["server"] } -sc-rpc = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sp-api = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-rpc-api = { version = "0.10.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sp-blockchain = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sp-block-builder = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -sc-basic-authorship = { version = "0.10.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -substrate-frame-rpc-system = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -pallet-transaction-payment-rpc = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +jsonrpsee = { features = ["server"] } +sc-rpc = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-api = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-rpc-api = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-blockchain = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sp-block-builder = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +sc-basic-authorship = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } # These dependencies are used for runtime benchmarking -frame-benchmarking = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } -frame-benchmarking-cli = { version = "4.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +frame-benchmarking = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } # Local Dependencies melodot-runtime = { version = "0.0.1", path = "../runtime" } +sc-network-das = { version = "0.0.1", path = "../crates/network-das" } +melo-core-primitives = { version = "0.1.0", path = "../crates/core-primitives" } # CLI-specific dependencies -try-runtime-cli = { version = "0.10.0-dev", optional = true, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +try-runtime-cli = { optional = true, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } [build-dependencies] -substrate-build-script-utils = { version = "3.0.0", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } +substrate-build-script-utils = { git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } [features] default = [] diff --git a/node/src/benchmarking.rs b/node/src/benchmarking.rs index 8f492e1..e24218c 100644 --- a/node/src/benchmarking.rs +++ b/node/src/benchmarking.rs @@ -4,7 +4,7 @@ use crate::service::FullClient; -use node_template_runtime as runtime; +use melodot_runtime as runtime; use runtime::{AccountId, Balance, BalancesCall, SystemCall}; use sc_cli::Result; use sc_client_api::BlockBackend; diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index 3dc3187..4448aa1 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -1,12 +1,45 @@ -use node_template_runtime::{ - AccountId, AuraConfig, BalancesConfig, GenesisConfig, GrandpaConfig, Signature, SudoConfig, +use melodot_runtime::{ + config::currency::DOLLARS, + opaque::SessionKeys, + AccountId, + AuthorityDiscoveryConfig, + BabeConfig, + BalancesConfig, + CouncilConfig, + DemocracyConfig, + GenesisConfig, + GrandpaConfig, + ImOnlineConfig, + ImOnlineId, + NominationPoolsConfig, + SessionConfig, + Signature, + StakerStatus, + StakingConfig, + SudoConfig, SystemConfig, // WASM_BINARY, + TechnicalCommitteeConfig, + WASM_BINARY, }; use sc_service::ChainType; -use sp_consensus_aura::sr25519::AuthorityId as AuraId; +use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +use sp_consensus_babe::AuthorityId as BabeId; use sp_consensus_grandpa::AuthorityId as GrandpaId; use sp_core::{sr25519, Pair, Public}; -use sp_runtime::traits::{IdentifyAccount, Verify}; +use sp_runtime::{ + traits::{IdentifyAccount, Verify}, + Perbill, +}; + +/// Helper function to generate crust session key +fn session_keys( + grandpa: GrandpaId, + babe: BabeId, + im_online: ImOnlineId, + authority_discovery: AuthorityDiscoveryId, +) -> SessionKeys { + SessionKeys { grandpa, babe, im_online, authority_discovery } +} // The URL for the telemetry server. // const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/"; @@ -31,9 +64,25 @@ where AccountPublic::from(get_from_seed::(seed)).into_account() } -/// Generate an Aura authority key. -pub fn authority_keys_from_seed(s: &str) -> (AuraId, GrandpaId) { - (get_from_seed::(s), get_from_seed::(s)) +/// Generate stash, controller and session key from seed. +pub fn authority_keys_from_seed( + seed: &str, +) -> ( + AccountId, + AccountId, + GrandpaId, + BabeId, + ImOnlineId, + AuthorityDiscoveryId, +) { + ( + get_account_id_from_seed::(&format!("{seed}//stash")), + get_account_id_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + get_from_seed::(seed), + ) } pub fn development_config() -> Result { @@ -127,11 +176,21 @@ pub fn local_testnet_config() -> Result { /// Configure initial storage state for FRAME modules. fn testnet_genesis( wasm_binary: &[u8], - initial_authorities: Vec<(AuraId, GrandpaId)>, + initial_authorities: Vec<( + AccountId, + AccountId, + GrandpaId, + BabeId, + ImOnlineId, + AuthorityDiscoveryId, + )>, root_key: AccountId, endowed_accounts: Vec, _enable_println: bool, ) -> GenesisConfig { + + const STASH: u128 = 20_000 * DOLLARS; + GenesisConfig { system: SystemConfig { // Add Wasm runtime to storage. @@ -141,16 +200,60 @@ fn testnet_genesis( // Configure endowed accounts with initial balance of 1 << 60. balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect(), }, - aura: AuraConfig { - authorities: initial_authorities.iter().map(|x| (x.0.clone())).collect(), - }, grandpa: GrandpaConfig { - authorities: initial_authorities.iter().map(|x| (x.1.clone(), 1)).collect(), + authorities: vec![], }, sudo: SudoConfig { // Assign network admin rights. key: Some(root_key), }, transaction_payment: Default::default(), + staking: StakingConfig { + validator_count: initial_authorities.len() as u32, + minimum_validator_count: initial_authorities.len() as u32, + invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(), + slash_reward_fraction: Perbill::from_percent(10), + stakers: initial_authorities + .iter() + .map(|x| (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator)) + .collect(), + ..Default::default() + }, + session: SessionConfig { + keys: initial_authorities + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone()), + ) + }) + .collect::>(), + }, + im_online: ImOnlineConfig { keys: vec![] }, + authority_discovery: AuthorityDiscoveryConfig { keys: vec![] }, + babe: BabeConfig { + authorities: vec![], + epoch_config: Some(melodot_runtime::GENESIS_EPOCH_CONFIG), + }, + nomination_pools: NominationPoolsConfig { + min_create_bond: 10 * DOLLARS, + #[allow(clippy::identity_op)] + min_join_bond: DOLLARS, + ..Default::default() + }, + technical_committee: TechnicalCommitteeConfig { + members: endowed_accounts + .iter() + .take((endowed_accounts.len() + 1) / 2) + .cloned() + .collect(), + phantom: Default::default(), + }, + technical_membership: Default::default(), + council: CouncilConfig::default(), + democracy: DemocracyConfig::default(), + treasury: Default::default(), } } diff --git a/node/src/command.rs b/node/src/command.rs index e121db8..911d508 100644 --- a/node/src/command.rs +++ b/node/src/command.rs @@ -5,7 +5,7 @@ use crate::{ service, }; use frame_benchmarking_cli::{BenchmarkCmd, ExtrinsicFactory, SUBSTRATE_REFERENCE_HARDWARE}; -use node_template_runtime::{Block, EXISTENTIAL_DEPOSIT}; +use melodot_runtime::{Block, EXISTENTIAL_DEPOSIT}; use sc_cli::{ChainSpec, RuntimeVersion, SubstrateCli}; use sc_service::PartialComponents; use sp_keyring::Sr25519Keyring; @@ -48,7 +48,7 @@ impl SubstrateCli for Cli { } fn native_runtime_version(_: &Box) -> &'static RuntimeVersion { - &node_template_runtime::VERSION + &melodot_runtime::VERSION } } diff --git a/node/src/rpc.rs b/node/src/rpc.rs index f6995e9..7034de0 100644 --- a/node/src/rpc.rs +++ b/node/src/rpc.rs @@ -8,45 +8,126 @@ use std::sync::Arc; use jsonrpsee::RpcModule; -use node_template_runtime::{opaque::Block, AccountId, Balance, Index}; +use melodot_runtime::{opaque::Block, AccountId, Balance, Index}; +use melodot_runtime::{BlockNumber, Hash}; +use sc_client_api::AuxStore; +use sc_consensus_babe::BabeWorkerHandle; +use sc_consensus_grandpa::{ + FinalityProofProvider, GrandpaJustificationStream, SharedAuthoritySet, SharedVoterState, +}; use sc_transaction_pool_api::TransactionPool; use sp_api::ProvideRuntimeApi; use sp_block_builder::BlockBuilder; use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; +use sp_consensus::SelectChain; +use sp_consensus_babe::BabeApi; +use sp_keystore::KeystorePtr; +pub use sc_rpc::SubscriptionTaskExecutor; pub use sc_rpc_api::DenyUnsafe; +/// Extra dependencies for BABE. +pub struct BabeDeps { + /// A handle to the BABE worker for issuing requests. + pub babe_worker_handle: BabeWorkerHandle, + /// The keystore that manages the keys of the node. + pub keystore: KeystorePtr, +} + +/// Extra dependencies for GRANDPA +pub struct GrandpaDeps { + /// Voting round info. + pub shared_voter_state: SharedVoterState, + /// Authority set info. + pub shared_authority_set: SharedAuthoritySet, + /// Receives notifications about justification events from Grandpa. + pub justification_stream: GrandpaJustificationStream, + /// Executor to drive the subscription manager in the Grandpa RPC handler. + pub subscription_executor: sc_rpc::SubscriptionTaskExecutor, + /// Finality proof provider. + pub finality_provider: Arc>, +} + /// Full client dependencies. -pub struct FullDeps { +pub struct FullDeps { /// The client instance to use. pub client: Arc, /// Transaction pool instance. pub pool: Arc

, + /// A copy of the chain spec. + pub chain_spec: Box, /// Whether to deny unsafe calls pub deny_unsafe: DenyUnsafe, + /// Whether to deny unsafe calls + pub select_chain: SC, + /// BABE specific dependencies. + pub babe: BabeDeps, + /// GRANDPA specific dependencies. + pub grandpa: GrandpaDeps, } /// Instantiate all full RPC extensions. -pub fn create_full( - deps: FullDeps, +pub fn create_full( + deps: FullDeps, ) -> Result, Box> where - C: ProvideRuntimeApi, - C: HeaderBackend + HeaderMetadata + 'static, - C: Send + Sync + 'static, + C: ProvideRuntimeApi + + sc_client_api::BlockBackend + + HeaderBackend + + AuxStore + + HeaderMetadata + + Sync + + Send + + 'static, C::Api: substrate_frame_rpc_system::AccountNonceApi, C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi, + C::Api: BabeApi, C::Api: BlockBuilder, P: TransactionPool + 'static, + SC: SelectChain + 'static, + B: sc_client_api::Backend + Send + Sync + 'static, + B::State: sc_client_api::backend::StateBackend>, { use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer}; + use sc_consensus_babe_rpc::{Babe, BabeApiServer}; + use sc_consensus_grandpa_rpc::{Grandpa, GrandpaApiServer}; + use sc_sync_state_rpc::{SyncState, SyncStateApiServer}; use substrate_frame_rpc_system::{System, SystemApiServer}; let mut module = RpcModule::new(()); - let FullDeps { client, pool, deny_unsafe } = deps; + let FullDeps { client, pool, chain_spec, deny_unsafe, select_chain, babe, grandpa } = deps; + + let BabeDeps { + babe_worker_handle, + keystore, + } = babe; + let GrandpaDeps { + shared_voter_state, + shared_authority_set, + justification_stream, + subscription_executor, + finality_provider, + } = grandpa; module.merge(System::new(client.clone(), pool, deny_unsafe).into_rpc())?; - module.merge(TransactionPayment::new(client).into_rpc())?; + module.merge(TransactionPayment::new(client.clone()).into_rpc())?; + module.merge( + Babe::new(client.clone(), babe_worker_handle.clone(), keystore, select_chain, deny_unsafe) + .into_rpc(), + )?; + module.merge( + Grandpa::new( + subscription_executor, + shared_authority_set.clone(), + shared_voter_state, + justification_stream, + finality_provider, + ) + .into_rpc(), + )?; + module.merge( + SyncState::new(chain_spec, client, shared_authority_set, babe_worker_handle)?.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 diff --git a/node/src/service.rs b/node/src/service.rs index 0fa7676..200fe47 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -1,15 +1,19 @@ //! Service and ServiceFactory implementation. Specialized wrapper over substrate service. -use node_template_runtime::{self, opaque::Block, RuntimeApi}; +use futures::prelude::*; +use melodot_runtime::{self, opaque::Block, RuntimeApi}; use sc_client_api::BlockBackend; -use sc_consensus_aura::{ImportQueueParams, SlotProportion, StartAuraParams}; use sc_consensus_grandpa::SharedVoterState; pub use sc_executor::NativeElseWasmExecutor; +use sc_network::{event::Event, NetworkEventStream}; +use sc_network_das::dht_work::Worker as DhtWorker; +use sc_network_das::tx_pool_listener::{start_tx_pool_listener, TPListenerParams}; use sc_service::{error::Error as ServiceError, Configuration, TaskManager, WarpSyncParams}; use sc_telemetry::{Telemetry, TelemetryWorker}; -use sp_consensus_aura::sr25519::AuthorityPair as AuraPair; use std::{sync::Arc, time::Duration}; +use crate::rpc as melo_rpc; + // Our native executor instance. pub struct ExecutorDispatch; @@ -22,26 +26,21 @@ impl sc_executor::NativeExecutionDispatch for ExecutorDispatch { type ExtendHostFunctions = (); fn dispatch(method: &str, data: &[u8]) -> Option> { - node_template_runtime::api::dispatch(method, data) + melodot_runtime::api::dispatch(method, data) } fn native_version() -> sc_executor::NativeVersion { - node_template_runtime::native_version() + melodot_runtime::native_version() } } +type FullBackend = sc_service::TFullBackend; pub(crate) type FullClient = sc_service::TFullClient>; -type FullBackend = sc_service::TFullBackend; type FullSelectChain = sc_consensus::LongestChain; -type FullImportQueue = sc_consensus::DefaultImportQueue; -type FullTransactionPool = sc_transaction_pool::FullPool; -type GrandpaComponents = ( - sc_consensus_grandpa::GrandpaBlockImport, - sc_consensus_grandpa::LinkHalf, - Option, -); +type FullGrandpaBlockImport = + sc_consensus_grandpa::GrandpaBlockImport; pub fn new_partial( config: &Configuration, @@ -50,9 +49,21 @@ pub fn new_partial( FullClient, FullBackend, FullSelectChain, - FullImportQueue, - FullTransactionPool, - GrandpaComponents, + sc_consensus::DefaultImportQueue, + sc_transaction_pool::FullPool, + ( + impl Fn( + melo_rpc::DenyUnsafe, + melo_rpc::SubscriptionTaskExecutor, + ) -> Result, sc_service::Error>, + ( + sc_consensus_babe::BabeBlockImport, + sc_consensus_grandpa::LinkHalf, + sc_consensus_babe::BabeLink, + ), + sc_consensus_grandpa::SharedVoterState, + Option, + ), >, ServiceError, > { @@ -99,40 +110,94 @@ pub fn new_partial( telemetry.as_ref().map(|x| x.handle()), )?; - let slot_duration = sc_consensus_aura::slot_duration(&*client)?; + let justification_import = grandpa_block_import.clone(); - let import_queue = - sc_consensus_aura::import_queue::(ImportQueueParams { - block_import: grandpa_block_import.clone(), - justification_import: Some(Box::new(grandpa_block_import.clone())), - client: client.clone(), - create_inherent_data_providers: move |_, ()| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - - let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( - *timestamp, - slot_duration, - ); - - Ok((slot, timestamp)) - }, - spawner: &task_manager.spawn_essential_handle(), - registry: config.prometheus_registry(), - check_for_equivocation: Default::default(), - telemetry: telemetry.as_ref().map(|x| x.handle()), - compatibility_mode: Default::default(), - })?; + let (babe_block_import, babe_link) = sc_consensus_babe::block_import( + sc_consensus_babe::configuration(&*client)?, + grandpa_block_import, + client.clone(), + )?; + + let slot_duration = babe_link.config().slot_duration(); + + let (import_queue, babe_worker_handle) = sc_consensus_babe::import_queue( + babe_link.clone(), + babe_block_import.clone(), + Some(Box::new(justification_import)), + client.clone(), + select_chain.clone(), + move |_, ()| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + + let slot = + sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration, + ); + + Ok((slot, timestamp)) + }, + &task_manager.spawn_essential_handle(), + config.prometheus_registry(), + telemetry.as_ref().map(|x| x.handle()), + )?; + + let import_setup = (babe_block_import, grandpa_link, babe_link); + + let (rpc_extensions_builder, rpc_setup) = { + let (_, grandpa_link, _) = &import_setup; + + let justification_stream = grandpa_link.justification_stream(); + let shared_authority_set = grandpa_link.shared_authority_set().clone(); + let shared_voter_state = sc_consensus_grandpa::SharedVoterState::empty(); + let shared_voter_state2 = shared_voter_state.clone(); + + let finality_proof_provider = sc_consensus_grandpa::FinalityProofProvider::new_for_service( + backend.clone(), + Some(shared_authority_set.clone()), + ); + + let client = client.clone(); + let pool = transaction_pool.clone(); + let select_chain = select_chain.clone(); + let keystore = keystore_container.keystore(); + let chain_spec = config.chain_spec.cloned_box(); + + let rpc_extensions_builder = move |deny_unsafe, subscription_executor| { + let deps = melo_rpc::FullDeps { + client: client.clone(), + pool: pool.clone(), + chain_spec: chain_spec.cloned_box(), + select_chain: select_chain.clone(), + deny_unsafe, + babe: melo_rpc::BabeDeps { + babe_worker_handle: babe_worker_handle.clone(), + keystore: keystore.clone(), + }, + grandpa: melo_rpc::GrandpaDeps { + shared_voter_state: shared_voter_state.clone(), + shared_authority_set: shared_authority_set.clone(), + justification_stream: justification_stream.clone(), + subscription_executor, + finality_provider: finality_proof_provider.clone(), + }, + }; + + melo_rpc::create_full(deps).map_err(Into::into) + }; + + (rpc_extensions_builder, shared_voter_state2) + }; Ok(sc_service::PartialComponents { client, backend, + select_chain, task_manager, import_queue, keystore_container, - select_chain, transaction_pool, - other: (grandpa_block_import, grandpa_link, telemetry), + other: (rpc_extensions_builder, import_setup, rpc_setup, telemetry), }) } @@ -141,12 +206,12 @@ pub fn new_full(mut config: Configuration) -> Result let sc_service::PartialComponents { client, backend, + select_chain: _select_chain, mut task_manager, import_queue, keystore_container, - select_chain, transaction_pool, - other: (block_import, grandpa_link, mut telemetry), + other: (rpc_extensions_builder, import_setup, _, mut telemetry), } = new_partial(&config)?; let grandpa_protocol_name = sc_consensus_grandpa::protocol_standard_name( @@ -154,10 +219,14 @@ pub fn new_full(mut config: Configuration) -> Result &config.chain_spec, ); + let (_, grandpa_link, _) = import_setup; + let auth_disc_publish_non_global_ips = config.network.allow_non_globals_in_dht; + config .network .extra_sets .push(sc_consensus_grandpa::grandpa_peers_set_config(grandpa_protocol_name.clone())); + let warp_sync = Arc::new(sc_consensus_grandpa::warp_proof::NetworkProvider::new( backend.clone(), grandpa_link.shared_authority_set().clone(), @@ -185,30 +254,17 @@ pub fn new_full(mut config: Configuration) -> Result } let role = config.role.clone(); - let force_authoring = config.force_authoring; - let backoff_authoring_blocks: Option<()> = None; let name = config.network.node_name.clone(); let enable_grandpa = !config.disable_grandpa; let prometheus_registry = config.prometheus_registry().cloned(); - let rpc_extensions_builder = { - let client = client.clone(); - let pool = transaction_pool.clone(); - - Box::new(move |deny_unsafe, _| { - let deps = - crate::rpc::FullDeps { client: client.clone(), pool: pool.clone(), deny_unsafe }; - crate::rpc::create_full(deps).map_err(Into::into) - }) - }; - let _rpc_handlers = sc_service::spawn_tasks(sc_service::SpawnTasksParams { network: network.clone(), client: client.clone(), keystore: keystore_container.keystore(), task_manager: &mut task_manager, transaction_pool: transaction_pool.clone(), - rpc_builder: rpc_extensions_builder, + rpc_builder: Box::new(rpc_extensions_builder), backend, system_rpc_tx, tx_handler_controller, @@ -217,52 +273,57 @@ pub fn new_full(mut config: Configuration) -> Result telemetry: telemetry.as_mut(), })?; - if role.is_authority() { - let proposer_factory = sc_basic_authorship::ProposerFactory::new( - task_manager.spawn_handle(), - client.clone(), - transaction_pool, - prometheus_registry.as_ref(), - telemetry.as_ref().map(|x| x.handle()), - ); + task_manager.spawn_essential_handle().spawn_blocking( + "new-blob-worker", + None, + start_tx_pool_listener(TPListenerParams { + client: client.clone(), + network: network.clone(), + transaction_pool: transaction_pool.clone(), + }), + ); - let slot_duration = sc_consensus_aura::slot_duration(&*client)?; - - let aura = sc_consensus_aura::start_aura::( - StartAuraParams { - slot_duration, - client, - select_chain, - block_import, - proposer_factory, - create_inherent_data_providers: move |_, ()| async move { - let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); - - let slot = - sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( - *timestamp, - slot_duration, - ); - - Ok((slot, timestamp)) - }, - force_authoring, - backoff_authoring_blocks, - keystore: keystore_container.keystore(), - sync_oracle: sync_service.clone(), - justification_sync_link: sync_service.clone(), - block_proposal_slot_portion: SlotProportion::new(2f32 / 3f32), - max_block_proposal_slot_portion: None, - telemetry: telemetry.as_ref().map(|x| x.handle()), - compatibility_mode: Default::default(), - }, - )?; + let dht_event_stream = network.event_stream("network-das").filter_map(|e| async move { + match e { + Event::Dht(e) => Some(e), + _ => None, + } + }); + + let dht_worker = DhtWorker::new(client.clone(), network.clone(), Box::pin(dht_event_stream)); + + task_manager + .spawn_essential_handle() + .spawn("dht-worker", None, dht_worker.run(|| {})); - // the AURA authoring task is considered essential, i.e. if it - // fails we take down the service with it. - task_manager - .spawn_essential_handle() - .spawn_blocking("aura", Some("block-authoring"), aura); + if role.is_authority() { + let authority_discovery_role = + sc_authority_discovery::Role::PublishAndDiscover(keystore_container.keystore()); + let dht_event_stream = + network.event_stream("authority-discovery").filter_map(|e| async move { + match e { + Event::Dht(e) => Some(e), + _ => None, + } + }); + let (authority_discovery_worker, _service) = + sc_authority_discovery::new_worker_and_service_with_config( + sc_authority_discovery::WorkerConfig { + publish_non_global_ips: auth_disc_publish_non_global_ips, + ..Default::default() + }, + client.clone(), + network.clone(), + Box::pin(dht_event_stream), + authority_discovery_role, + prometheus_registry.clone(), + ); + + task_manager.spawn_handle().spawn( + "authority-discovery-worker", + Some("networking"), + authority_discovery_worker.run(), + ); } if enable_grandpa { @@ -271,7 +332,6 @@ pub fn new_full(mut config: Configuration) -> Result let keystore = if role.is_authority() { Some(keystore_container.keystore()) } else { None }; let grandpa_config = sc_consensus_grandpa::Config { - // FIXME #1578 make this available through chainspec gossip_duration: Duration::from_millis(333), justification_period: 512, name: Some(name), diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 80ab195..f1623ba 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -21,6 +21,7 @@ codec = { package = "parity-scale-codec", version = "3.2.2", default-features = scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } static_assertions = "1.1.0" melo-auto-config = { version = "0.9.42", default-features = false, path="../crates/auto-config" } +# parity-scale-codec = { package = "parity-scale-codec", version = "3.3", default-features = false} # Substrate pallet-babe = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } @@ -48,6 +49,7 @@ pallet-offences = { default-features = false, git = "https://github.com/parityte pallet-session = { features = ['historical'], default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } pallet-staking = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } +pallet-utility = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.42", default-features = false } frame-election-provider-support = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } frame-support = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.42" } @@ -85,6 +87,7 @@ frame-system-benchmarking = { default-features = false, git = "https://github.co frame-executive-ext = { default-features = false, path = "../crates/frame-executive-ext" } frame-system-ext = { default-features = false, path = "../crates/frame-system-ext" } melo-core-primitives = { version = "0.1.0", default-features = false, path = "../crates/core-primitives"} +melo-das-primitives = { version = "0.1.0", default-features = false, path = "../crates/das-primitives"} pallet-melo-store = { version = "0.1.0", default-features = false, path = "../crates/pallet-melo-store" } [build-dependencies] @@ -147,6 +150,7 @@ std = [ "pallet-bounties/std", "pallet-preimage/std", "pallet-membership/std", + "pallet-utility/std", "sp-staking/std", "node-primitives/std", ] @@ -167,6 +171,8 @@ runtime-benchmarks = [ "pallet-bounties/runtime-benchmarks", "pallet-preimage/runtime-benchmarks", "pallet-membership/runtime-benchmarks", + "pallet-utility/runtime-benchmarks", + ] try-runtime = [ "frame-try-runtime/try-runtime", @@ -191,4 +197,5 @@ try-runtime = [ "pallet-bounties/try-runtime", "pallet-preimage/try-runtime", "pallet-membership/try-runtime", + "pallet-utility/try-runtime", ] diff --git a/runtime/build.rs b/runtime/build.rs index 7bb1448..c03d618 100644 --- a/runtime/build.rs +++ b/runtime/build.rs @@ -1,10 +1,10 @@ fn main() { - // #[cfg(feature = "std")] - // { - // substrate_wasm_builder::WasmBuilder::new() - // .with_current_project() - // .export_heap_base() - // .import_memory() - // .build(); - // } + #[cfg(feature = "std")] + { + substrate_wasm_builder::WasmBuilder::new() + .with_current_project() + .export_heap_base() + .import_memory() + .build(); + } } diff --git a/runtime/src/apis.rs b/runtime/src/apis.rs index 56f7914..c307e26 100644 --- a/runtime/src/apis.rs +++ b/runtime/src/apis.rs @@ -18,18 +18,24 @@ use frame_support::traits::KeyOwnerProofSystem; use pallet_grandpa::AuthorityId as GrandpaId; use sp_api::impl_runtime_apis; +use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +use sp_core::H256; use sp_runtime::{ + create_runtime_str, traits::NumberFor, transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, create_runtime_str, + ApplyExtrinsicResult, }; -use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +use sp_std::vec; use crate::{ - AccountId, AuthorityDiscovery, Babe, Balance, Block, BlockT, consensus::EpochDuration, opaque::SessionKeys, - Executive, Grandpa, Historical, Index, InherentDataExt, KeyTypeId, OpaqueMetadata, Runtime, - RuntimeCall, RuntimeVersion, System, TransactionPayment, Weight, consensus::GENESIS_EPOCH_CONFIG + consensus::EpochDuration, consensus::GENESIS_EPOCH_CONFIG, opaque::SessionKeys, AccountId, + AuthorityDiscovery, Babe, Balance, Block, BlockT, Executive, Grandpa, Historical, Index, + InherentDataExt, KeyTypeId, OpaqueMetadata, Runtime, RuntimeCall, RuntimeVersion, System, + TransactionPayment, UncheckedExtrinsic, Vec, Weight, }; +use codec::Decode; +use melo_das_primitives::{KZGCommitment, KZGProof}; #[sp_version::runtime_version] pub const VERSION: RuntimeVersion = RuntimeVersion { @@ -44,6 +50,39 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { }; impl_runtime_apis! { + impl melo_core_primitives::traits::Extractor for Runtime { + fn extract( + extrinsic: &Vec, + ) -> Option, Vec)>> { + // Decode the unchecked extrinsic + let extrinsic = UncheckedExtrinsic::decode(&mut &extrinsic[..]).ok()?; + + fn filter(call: RuntimeCall) -> Vec<(H256, u32, Vec, Vec)> { + match call { + RuntimeCall::MeloStore(pallet_melo_store::Call::submit_data { + app_id: _, + bytes_len, + data_hash, + commitments, + proofs, + }) => vec![(data_hash, bytes_len, commitments, proofs)], + RuntimeCall::Utility(pallet_utility::Call::batch { calls }) + | RuntimeCall::Utility(pallet_utility::Call::batch_all { calls }) + | RuntimeCall::Utility(pallet_utility::Call::force_batch { calls }) => process_calls(calls), + _ => vec![], + } + } + + fn process_calls( + calls: Vec, + ) -> Vec<(H256, u32, Vec, Vec)> { + calls.into_iter().flat_map(filter).collect() + } + + Some(process_calls(vec![extrinsic.function])) + } + } + impl sp_api::Core for Runtime { fn version() -> RuntimeVersion { VERSION diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 8f056c9..d749fc7 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1,13 +1,31 @@ +// This file is part of Substrate. + +// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #![cfg_attr(not(feature = "std"), no_std)] // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256. #![recursion_limit = "256"] // Make the WASM binary available. -// #[cfg(feature = "std")] -// include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +#[cfg(feature = "std")] +include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); pub mod config; -use config::{consensus, core::*, currency::*, gov, system}; +pub use config::core::*; +use config::{consensus, currency::*, gov, system}; pub mod apis; pub use apis::*; @@ -33,7 +51,7 @@ use frame_election_provider_support::{ onchain, BalancingConfig, ElectionDataProvider, SequentialPhragmen, VoteWeight, }; use pallet_election_provider_multi_phase::SolutionAccuracyOf; -use pallet_im_online::sr25519::AuthorityId as ImOnlineId; +pub use pallet_im_online::sr25519::AuthorityId as ImOnlineId; use pallet_session::historical as pallet_session_historical; #[cfg(feature = "std")] pub use pallet_staking::StakerStatus; @@ -74,6 +92,9 @@ pub use sp_runtime::{FixedU128, Perbill, Permill}; use melo_core_primitives::Header as ExtendedHeader; +pub use consensus::GENESIS_EPOCH_CONFIG; +pub use system::BlockHashCount; + /// An index to a block. pub type BlockNumber = u32; @@ -160,7 +181,7 @@ impl frame_system::Config for Runtime { /// The ubiquitous origin type. type RuntimeOrigin = RuntimeOrigin; /// Maximum number of block number to block hash mappings to keep (oldest pruned first). - type BlockHashCount = system::BlockHashCount; + type BlockHashCount = BlockHashCount; /// The weight of database operations that the runtime can invoke. type DbWeight = RocksDbWeight; /// Version of the runtime. @@ -197,6 +218,12 @@ impl pallet_authorship::Config for Runtime { type EventHandler = (Staking, ImOnline); } +#[auto_config] +impl pallet_utility::Config for Runtime { + type RuntimeCall = RuntimeCall; + type PalletsOrigin = OriginCaller; +} + use sp_runtime::traits::Convert; pub struct BalanceToU256; impl Convert for BalanceToU256 { @@ -700,6 +727,7 @@ construct_runtime!( // Basic stuff. System: frame_system, Timestamp: pallet_timestamp, + Utility: pallet_utility, // Consensus support. Babe: pallet_babe,